Java中线程的同步
-
05-07-2019 - |
题
我的应用程序中有一个自制的Web服务器。此Web服务器为进入要接受的套接字的每个请求生成一个新线程。我希望Web服务器等到它刚创建的线程中的特定点被命中。
我已经浏览过本网站上的很多帖子和网络上的例子,但是在我告诉线程等待之后,无法继续使用Web服务器。一个基本的代码示例会很棒。
synchronized关键字是否是正确的方法?如果是这样,怎么能实现呢?代码示例在我的应用程序下面:
Web服务器
while (true) {
//block here until a connection request is made
socket = server_socket.accept();
try {
//create a new HTTPRequest object for every file request
HttpRequest request = new HttpRequest(socket, this);
//create a new thread for each request
Thread thread = new Thread(request);
//run the thread and have it return after complete
thread.run();
///////////////////////////////
wait here until notifed to proceed
///////////////////////////////
} catch (Exception e) {
e.printStackTrace(logFile);
}
}
线程代码
public void run() {
//code here
//notify web server to continue here
}
更新 - 最终代码如下。每当我发送响应头时, HttpRequest
就会调用 resumeListener.resume()
(当然还将接口添加为单独的类和 addResumeListener(ResumeListener r1)
方法: HttpRequest
)中的
网络服务器部分
// server infinite loop
while (true) {
//block here until a connection request is made
socket = server_socket.accept();
try {
final Object locker = new Object();
//create a new HTTPRequest object for every file request
HttpRequest request = new HttpRequest(socket, this);
request.addResumeListener(new ResumeListener() {
public void resume() {
//get control of the lock and release the server
synchronized(locker) {
locker.notify();
}
}
});
synchronized(locker) {
//create a new thread for each request
Thread thread = new Thread(request);
//run the thread and have it return after complete
thread.start();
//tell this thread to wait until HttpRequest releases
//the server
locker.wait();
}
} catch (Exception e) {
e.printStackTrace(Session.logFile);
}
}
解决方案
首先,我赞同其他人的观点,即在这里重新发明轮子很可能会为你带来各种各样的问题。但是,如果你想沿着这条路走下去,那么你要做的事情并不困难。您是否尝试过Jetty?
也许是这样的:
public class MyWebServer {
public void foo() throws IOException {
while (true) {
//block here until a connection request is made
ServerSocket socket = new ServerSocket();
try {
final Object locker = new Object();
//create a new HTTPRequest object for every file request
MyRequest request = new MyRequest(socket);
request.addResumeListener(new ResumeListener() {
public void resume() {
locker.notify();
}
});
synchronized(locker){
//create a new thread for each request
Thread thread = new Thread(request);
//start() the thread - not run()
thread.start();
//this thread will block until the MyRequest run method calls resume
locker.wait();
}
} catch (Exception e) {
}
}
}
}
public interface ResumeListener {
public void resume();
}
public class MyRequest implements Runnable{
private ResumeListener resumeListener;
public MyRequest(ServerSocket socket) {
}
public void run() {
// do something
resumeListener.resume(); //notify server to continue accepting next request
}
public void addResumeListener(ResumeListener rl) {
this.resumeListener = rl;
}
}
其他提示
您可以使用 java.util.concurrent .CountDownLatch ,计数为1。安排由父子线程创建和共享它的实例(例如,在 HttpRequest
的构造函数中创建它,并让它由成员函数检索)。然后服务器在其上调用 await()
,当线程准备好释放其父级时,线程将命中 countDown()
。
您可能需要使用Java 条件。来自文档:
条件(也称为条件 队列或条件变量)提供 一个线程暂停的方法 执行(到“等待”)直到通知 一些状态的另一个线程 条件现在可能是真的。
在调试器下运行并设置断点?
如果不可行,请从System.in读取一行?