【发布时间】:2020-05-13 05:32:18
【问题描述】:
我有一个服务器和两个客户端,服务器启动两个线程(ServerHandler),它们都通过相应客户端的Socket TCP连接开始连接到服务器。
预期行为:
一个 ServerHandler 线程向客户端发送消息,而另一个 ServerHandler 线程等待wait() ...然后工作线程通知睡眠线程并等待...等等。
实际行为:
两个 ServerHandlers 同时等待。他们都进入了不应该出现的同步块,一个线程应该在等待,而另一个线程工作。
ServerHandler 的代码 sn-p(它的两个实例正在运行)
private static Object lock = new Object();
...
@Override
public void run() {
System.out.println(String.format(" --> Server handler: %s is in run method...", serverID));
while (true) {
synchronized (lock){
while (!Server.isFinished()) {
try {
System.out.println(String.format(" --> Server handler: %s is waiting...", serverID));
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
System.out.println(String.format(" --> Server handler: %s is ready to send board...", serverID));
Server.setFinished(true);
sendBoard();
notify();
}
}
}
注意:
Server 类启动两个 ServerHandler 线程。 finished 默认设置为 false
输出:
CLIENT connected!
<-- I'M Alan I want to play!
--> Server handler 1 instantiated!
CLIENT connected!
<-- I'M Bot I want to play!
--> Server handler 2 instantiated!
HANDLER started...
HANDLER started...
--> Server handler: 1 is in run method...
--> Server handler: 2 is in run method...
--> Server handler: 1 is waiting...
--> Server handler: 2 is waiting...
预期行为:
CLIENT connected!
<-- I'M Bot I want to play!
--> Server handler 1 instantiated!
CLIENT connected!
<-- I'M Alan I want to play!
--> Server handler 2 instantiated!
HANDLER started...
HANDLER started...
--> Server handler: 1 is in run method...
--> Server handler: 1 is waiting...
--> Server handler: 2 is in run method...
--> Server handler: 2 is ready to send board...
...
谢谢!
【问题讨论】:
-
所以你有 ServerHandler 实例 s1 和 s2; s1 调用 s1.wait(),s2 调用 s2.wait()。谁调用 s1.notify() ?
-
我以为第一次访问同步块会阻止它,实际上会发送板我的错是什么?
-
第一个进入同步块的线程发现Server.isFinished()=false,调用wait()。 (见docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait())。所以这个线程进入等待状态(它被暂停),并且释放监视器。下一个线程获取监视器并进入等待状态。
-
虽然实际上 - 他们打电话给
synchronized(this)?在这种情况下,每个服务器处理程序都在自己的监视器上进行侦听(并且只能被唤醒,但只能通知该监视器)。 -
我现在在服务器处理程序中创建了一个静态对象锁,并且我在这个对象上进行了同步。但仍然是同样的问题。将设置完成的变量。在等待解决方案之前?
标签: java multithreading synchronized