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 修改共享BlockingQueue的2个线程的意外输出_Java_Multithreading - Fatal编程技术网

Java 修改共享BlockingQueue的2个线程的意外输出

Java 修改共享BlockingQueue的2个线程的意外输出,java,multithreading,Java,Multithreading,我有以下几点: public class ProducerConsumer { private BlockingQueue<Integer> q; private Random rnd; private boolean run; public ProducerConsumer(){ rnd = new Random(); q = new ArrayBlockingQueue<>(10); run = true; } /

我有以下几点:

public class ProducerConsumer {

  private BlockingQueue<Integer> q;
  private Random rnd;
  private boolean run;

  public ProducerConsumer(){
    rnd = new Random();
    q = new ArrayBlockingQueue<>(10);
    run = true;
  }

  // high leve - with ArrayBlockingQueue

  public void QProducer() throws InterruptedException{       
    int i;
    while(run){
        i  = rnd.nextInt(100);

        q.put(i);
        System.out.println(i +" Added. Size is: "+ q.size());
    }
  } 

  public void  QConsumer() throws InterruptedException{
    int i;
    while(run){
      Thread.sleep(100);
      if (rnd.nextInt(10) == 0) {

          i = q.take();
          System.out.println(i + " Taken. Size is: "+ q.size());
      }
    }
  }

public void changeRun(){
    run = false;
 }    
}
输出:

20 Added. Size is: 1
8 Added. Size is: 2
71 Added. Size is: 3
72 Added. Size is: 4
61 Added. Size is: 5
97 Added. Size is: 6
6 Added. Size is: 7
64 Added. Size is: 8
58 Added. Size is: 9
27 Added. Size is: 10
20 Taken. Size is: 10 *
93 Added. Size is: 10
8 Taken. Size is: 9
95 Added. Size is: 10
71 Taken. Size is: 10 *
70 Added. Size is: 10
72 Taken. Size is: 10 *
85 Added. Size is: 10
61 Taken. Size is: 9
43 Added. Size is: 10
64 Added. Size is: 10 **
... 
我想知道怎么会有数字,但大小保持不变(*), 在队列已满(**)之后添加howcome值。 在AIU中,BlockingQueue被同步化,并等待在队列为空时添加值,在队列为满时删除值。
提前谢谢。

由于您没有
已同步的
块,因此
put
操作对于
大小
查询不是原子的。正如您所看到的,在这两个线程之间,其他线程可以执行任意数量的操作。

因为您没有同步的
块,所以
put
操作对于
size
查询不是原子的。正如您所看到的,在这两个线程之间,其他线程可以执行任意数量的操作。

它后面的
put()
println/size()
,以及它后面的
take()
println/size()。因此,
size()
返回的值在打印时可能已过期。例如

1a. Add (size = 10)
  1b. Print size 10
2a. Take (size = 9)
3a. Add (size = 10)
  2b. Print size 10
  3b. Print size 10
由于多线程,它后面的
put()
println/size()
以及它后面的
take()
println/size()
可以交错。因此,
size()
返回的值在打印时可能已过期。例如

1a. Add (size = 10)
  1b. Print size 10
2a. Take (size = 9)
3a. Add (size = 10)
  2b. Print size 10
  3b. Print size 10
正如我所怀疑(但不能批准)正如我所怀疑(但不能批准)