Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 同步方法可以有竞争条件吗?[示例]_Java_Multithreading_Race Condition - Fatal编程技术网

Java 同步方法可以有竞争条件吗?[示例]

Java 同步方法可以有竞争条件吗?[示例],java,multithreading,race-condition,Java,Multithreading,Race Condition,我正在学习将同步方法作为防止Java中的竞争条件和不必要行为的一种手段。有人向我介绍了以下示例,并告诉我比赛条件非常微妙: public class Messages { private String message = null; private int count = 2; // invariant 0 <= count && count <= 2 public synchronized void put(String message) {

我正在学习将同步方法作为防止Java中的竞争条件和不必要行为的一种手段。有人向我介绍了以下示例,并告诉我比赛条件非常微妙:

public class Messages {
  private String message = null;
  private int count = 2;

  // invariant 0 <= count && count <= 2

  public synchronized void put(String message) {
    while( count < 2 )
      this.wait();
    this.message = message;
    this.count = 0; 
    this.notifyAll(); 
  }

  public synchronized String getMessage() {
    while( this.count == 2 )
      this.wait();
    String result = this.message;
    this.count += 1;
    this.notifyAll();
    return result; 
  }
}
公共类消息{
私有字符串消息=null;
私有整数计数=2;

//不变0多线程是指使用新线程(runnable).start()时;这将启动一个新线程并转到run()方法。runnable是任何实现runnable的类。或扩展线程。同步方法确保,如果这些线程希望读取由同步方法更改的数据,那么它将是可能的,否则它可能会保持不变,或者更糟糕的是,更改了一半。

我猜想作者想到的是,由于计数从0到2,两个线程可能依次调用
put()
,因此读卡器线程将错过其中一条消息


这确实是一个竞争条件:读卡器和推杆争夺同一个锁,如果正在读取的消息取决于
notifyAll()

Java的同步方法会让你在这两个方法之间互斥,这意味着你可以假设它们不会交错

但是,您仍然有一个竞争条件,因为根据首先运行哪个方法,您可以获得不同的行为


正如JB Nizet在他的回答中所建议的,考虑这两个排序中的每一个发生了什么(假设它们在不同的线程中运行)。
这段代码也有一股难闻的味道。什么是计数?为什么要递增它,然后重置它?为什么不必要地使用“this”?如果我在项目中看到这样的代码,我会非常仔细地看它…

每当两个实体争夺一个资源时,就会出现竞争情况,这可能会导致不可预测的行为如果结果取决于顺序,则vior。当您使用notifyAll()时,所有线程都会被唤醒,它们会竞相获取等待的锁,并且无法确定下一个将执行哪个锁。

对于这样的问题,我总是会盲目地回答“是”(仅基于标题).Ahhh,我想我明白了。顺序很重要,因为count被初始化为2,getMessage将首先执行。它的等待将释放锁,并且,当它试图获取消息时,消息将永远不会通过put加载?请用示例代码更清楚地解释一下。作为一个独立的竞态条件示例,我假设它不应该被加载太好了。我只是想分析一下。我认为你的指针是有意义的,而且似乎符合我现在的想法,基于我对另一个答案的评论!谢谢!你能详细说明一下打破OP示例的交错吗?我一直在试着找一个,因为我很好奇,我无法找到。如果两个单独的线程调用
put
,则第一个将设置
计数=0
,第二个将
等待()
.Hmm,你说得对。@Rome\u Leader你能不能不接受这个答案,这样我就可以删除它。对不起,请用示例代码再解释一下。我不明白竞态条件是如何实现的。请用示例代码场景解释解决方案。