java 我的布尔值上的System.out.println使我的程序能够验证布尔值

gcmastyq  于 2022-11-27  发布在  Java
关注(0)|答案(2)|浏览(193)

我的程序基于两个共享协议对象的线程。根据共享协议对象中的布尔值,我试图让另一个线程在使用协议之前等待。
主服务器:

GameProtocol protocol = new GameProtocol();
MyThreadedClass thread1 = new MyThreadedClass(protocol);
MyThreadedClass thread2 = new MyThreadedClass(protocol);
thread1.start()
thread2.start()

螺纹类别:

GameProtocol protocol;

private MyThreadedClass(GameProtocol protocol){
   this.protocol = protocol
}

private GamePackage waitCheck(GamePackage gp){
   if(!gp.isWaiting()) {
      return protocol.update(gp);
   }
   while(protocol.waitForCategory) {
      //System.out.println(protocol.waitForCategory);
   }
   return protocol.update(gp);
}

通信协定类别:

boolean waitForCategory = false;

public synchronized GamePackage update(GamePackage gp){

   if(gp.myTurnToPickCategory){
      gp.setWaiting(false);
      waitForCategory = true;
   } else {
     gp.setWaiting(true);
     waitForCategory = false;
   }
   return gp;
}

现在我的意图是让一个线程等待,直到另一个线程第二次使用update方法。但是第二个线程在while循环中卡住了,即使布尔值waitForCategory被设置为false。一旦我添加了System.out.println(protocol.waitForCategory);行,它就开始工作了。如果我把它移走,它又会停止工作。我似乎不明白布尔值上的一个sout是如何使它工作的。如果有人明白这一点,有可能用另一种方法来解决它吗?因为在这样的循环中有一个sout会使它很混乱。

yyhrrdl8

yyhrrdl81#

Here is the explanation for why println makes the code work: stackoverflow.com/q/25425130/217324 – Nathan Hughes

6ojccjat

6ojccjat2#

正如其他人已经解释的那样,println()的引入将同步插入到图片中,因此您的代码给人一种它工作的错觉。
为了解决这个问题,你必须确保所有的东西都是正确同步的。换句话说,gp.isWaiting()也必须同步,并且protocol.waitForCategory必须移动到一个方法中并同步。
或者,停止尝试使用同步,改用通过java.util.concurrent.BlockingQueue的异步消息传递。您的代码将执行得更好,您将不会面临争用条件的危险,并且您的代码也将是可测试的。(而使用同步,您的代码将永远是不可测试的,因为没有任何测试会捕获争用条件。)

相关问题