首页 > 解决方案 > 两个线程都停留在Java中的等待状态

问题描述

我有一个服务器和两个客户端,服务器启动两个线程(ServerHandler),它们都通过Socket相应客户端的 TCP 连接开始连接到服务器。

预期行为:
一个 ServerHandler 线程向客户端发送消息,而另一个 ServerHandler 线程等待wait()......然后工作线程通知睡眠线程并等待......等等。

实际行为:
两个 ServerHandler 同时等待。他们都进入了不应该出现的同步块,一个线程应该在等待而另一个线程工作。

ServerHandler 的代码片段(它的两个实例正在运行)

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...
...

谢谢!

标签: javamultithreadingsynchronized

解决方案


您能否提供一些示例来说明您的预期输出是什么?

似乎是一个意外错误的一件事是两个线程都有自己的锁,而不是共享一个(注意static)。

另一件没有意义的事情是在您已经拥有的锁上调用notify

private static Object lock = new Object();

public void run() {
    while (true) {
        synchronized (lock) {
            while (!Server.isFinished()) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }

            Server.setFinished(true);
            sendBoard();
        }
    }
}

推荐阅读