在Java中,两个线程都处于等待状态
我有一个服务器和两个客户机,服务器启动两个线程(ServerHandler),这两个线程都通过相应客户机的在Java中,两个线程都处于等待状态,java,multithreading,synchronized,Java,Multithreading,Synchronized,我有一个服务器和两个客户机,服务器启动两个线程(ServerHandler),这两个线程都通过相应客户机的SocketTCP连接,这些客户机在开始时连接到服务器 预期行为: 一个ServerHandler线程向客户端发送消息,而另一个ServerHandler线程等待wait()。。。然后工作线程通知睡眠线程并等待。。。等等 实际行为: 两个服务器处理程序同时等待。它们都进入了synchronized块,而这种情况不应该发生,一个线程应该在等待,而另一个线程则在工作 服务器处理程序的代码片段(它
Socket
TCP连接,这些客户机在开始时连接到服务器
预期行为:一个ServerHandler线程向客户端发送消息,而另一个ServerHandler线程等待
wait()
。。。然后工作线程通知睡眠线程并等待。。。等等
实际行为:两个服务器处理程序同时等待。它们都进入了synchronized块,而这种情况不应该发生,一个线程应该在等待,而另一个线程则在工作 服务器处理程序的代码片段(它的两个实例正在运行)
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();
}
}
}
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...
...
注意:
Server
类启动两个ServerHandler线程<默认情况下,代码>已完成设置为false
输出:
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();
}
}
}
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...
...
客户端已连接!
服务器处理程序2已实例化!
处理程序已启动。。。
处理程序已启动。。。
-->服务器处理程序:1正在运行方法。。。
-->服务器处理程序:2正在运行方法。。。
-->服务器处理程序:1正在等待。。。
-->服务器处理程序:2正在等待。。。
预期行为:
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();
}
}
}
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...
...
客户端已连接!
服务器处理程序2已实例化!
处理程序已启动。。。
处理程序已启动。。。
-->服务器处理程序:1正在运行方法。。。
-->服务器处理程序:1正在等待。。。
-->服务器处理程序:2正在运行方法。。。
-->服务器处理程序:2已准备好发送板。。。
...
谢谢 你能举例说明你的预期产出吗 一个看起来像是意外错误的事情是两个线程都有自己的锁,而不是一个共享的锁(注意static) 另一件没有意义的事情是调用您已经拥有的锁
private static Object lock=new Object();
公开募捐{
while(true){
已同步(锁定){
而(!Server.isFinished()){
试一试{
lock.wait();
}捕捉(中断异常e){
Thread.currentThread().interrupt();
}
}
setFinished(true);
发送板();
}
}
}
您能提供一些您预期输出的示例吗
一个看起来像是意外错误的事情是两个线程都有自己的锁,而不是一个共享的锁(注意static)
另一件没有意义的事情是调用您已经拥有的锁
private static Object lock=new Object();
公开募捐{
while(true){
已同步(锁定){
而(!Server.isFinished()){
试一试{
lock.wait();
}捕捉(中断异常e){
Thread.currentThread().interrupt();
}
}
setFinished(true);
发送板();
}
}
}
不确定您在此处使用的同步机制是否正确
你的流程如下
您可能想考虑使用例如A。这将让您等待,直到您收集了足够的线程开始游戏
private static Object lock = new Object();
private static CyclicBarrier barrier = new CyclicBarrier(2, () -> setReady());
...
@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));
sendBoard();
notify();
}
}
}
public static void setReady() {
synchronized (lock) {
try {
sendBoard();
System.out.println(String.format(" --> Server handler: %s is waiting...", serverID));
lock.notify();
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
类似这样的方法可以让您更改块,直到两个线程都启动,第二个线程到达屏障,然后触发setReady方法发送电路板,然后再等待另一个线程。不确定您在这里使用的同步机制是否正确 你的流程如下
您可能想考虑使用例如A。这将让您等待,直到您收集了足够的线程开始游戏
private static Object lock = new Object();
private static CyclicBarrier barrier = new CyclicBarrier(2, () -> setReady());
...
@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));
sendBoard();
notify();
}
}
}
public static void setReady() {
synchronized (lock) {
try {
sendBoard();
System.out.println(String.format(" --> Server handler: %s is waiting...", serverID));
lock.notify();
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
类似这样的东西可以让您更改块,直到两个线程都启动,第二个线程到达屏障,然后触发setReady方法,在等待另一个线程之前发送电路板。您必须在
lock
对象上调用notify
。您必须在lock
对象上调用notify
。我编辑了我的问题(请参见预期行为)当我将它们锁定在静态对象上(如您所写)时,线程“thread-0”java.lang.IllegalMonitorStateException中的异常被抛出(在wait()
语句中),您能再试一次吗?只有在对不拥有的锁调用wait()
时才会引发异常。在这种情况下,lock.wait()
在synchronized(lock)
块中被明确调用,因此必须为其所有。我尝试了5次,始终是一个非法监视器。。。例外情况您确定已将synchronized(此)
更改为synchronized(锁定)
?更新:我忘了写