我的登录Servlet收到请求,响应后睡眠1分钟。
我的目标是允许两个请求具有访问权限,并且如果第三个事务到达,它必须等待,直到其他线程中的任何一个完成各自的任务。
我的代码检查哪些线程正在休眠,哪些线程没有休眠。我遇到的问题是当线程唤醒它时,我希望能够为其分配任务。我需要轮询还是有某种同步方法?我该如何处理?
public class Home extends HttpServlet
{
static HttpSession ses;
static List<Thread> homethread = new ArrayList<Thread>();
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
ses = request.getSession();
homethread.add(Thread.currentThread());
for(Thread th : homethread)
{
if(th.getState()!=Thread.State.TIMED_WAITING)
{
System.out.println("This Thread is Not in Waiting State -> "+th.getName()+"Its State -> "+th.getState());
}
else
{
System.out.println("A Thread Is In Waiting State -> "+th.getName()+"Its State -> "+th.getState());
}
System.out.println("Thread Details->"+th+"Thread State->"+th.getState().TIMED_WAITING);
}
response.setContentType("text/html");
PrintWriter writter = response.getWriter();
writter.println
(
"<!DOCTYPE html>" +
"<html>" +
"<body>" +
"<img src=\"C:\\Users\\surya-pt3101\\Pictures\\Screenshots\\Screenshot (1).png\">"+
"<h1 style=\"text-align:center;\">Provide Your Choice</h1>"+
"<form action=\"Upload\" method=\"POST\" enctype=\"multipart/form-data\">" +
"<div style=\"text-align:center\">Upload File :<input type=\"file\" name=\"UploadedFile\" multiple/><input type=\"submit\" value=\"Upload\"><br><br>"+
"</form>" +
"<div style=\"text-align:center\">View Files :<input type=\"submit\" formaction=\"View\" formmethod=\"post\" value=\"View\"/><br><br>" +
"<div style=\"text-align:center\"><input type=\"submit\" formaction=\"LogOut\" formmethod=\"post\" value=\"LogOut\"/>" +
"</body>" +
"</html>"
);
response.flushBuffer();
try
{
Thread.currentThread().sleep(60000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
Servlet根据定义必须是线程安全的。 Tomcat(或任何其他servlet容器)内部包含将执行您的请求的线程池。因此,在生成您自己的线程时,我觉得没有多大意义(当然,如果我们要谈论的不是非常困难的计算)。为了使您的类线程安全,有几种选择:常用的同步方法(例如,synchronized / wait / notify)或更高级的结构(请参见java.util.concurrent包)。应避免使用其他共享的非线程安全对象,例如ArrayLists。据我了解,您希望同时执行不超过2个线程。您写了“必须在完成的线程中处理第三个请求”-在我看来,如果您能够在servlet线程中执行所有需要的计算,那是不合理的。下面是一个使用java.util.concurrent.Semaphore的代码段-该类仅允许一次只处理'n'个线程,其中n是允许的数量。
public class Home extends HttpServlet {
private final Semaphore semaphore = new Semaphore(2);
protected void service(HttpServletRequest request, HttpServletResponse response) {
try {
semaphore.acquire();
// Do what you need
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
semaphore.release();
}
}
}
UPD:加载程序示例
让我们假设您有一个带有字段和提交按钮的表单。单击时,需要执行一些长时间的操作,因此您要向用户显示加载程序gif。
HTML文件的一部分:
<form>
<label for="content">Enter value:</label>
<input id="content" type="text" name="content">
<button id="submitBtn" type="submit">Send</button>
<img id="loader" style="display:none" src="../static/img/loading.gif">
</form>
JS(使用jQuery):
function sendRequest(content) {
var payload = {};
payload.content = content;
return $.ajax({
type: 'POST',
contentType: "application/json",
url: '/your-endpoint',
data: JSON.stringify(payload)
})
}
$("#submitBtn").click(function () {
$('#loader').show();
$('#submitBtn').prop('disabled', true);
const response = sendRequest($('#content').val());
response.then((result) => {
$('#loader').hide();
$('#submitBtn').prop('disabled', false);
$('#content').val("");
alert(result);
}).catch(error => {
$('#loader').hide();
$('#submitBtn').prop('disabled', false);
$('#content').val("");
alert(error);
});
return false;
});
希望有帮助。