2016-11-20 46 views
1

我得到了一個代碼,我試圖運行它提供未預期的輸出。消費者生產者錯誤中的意外輸出

代碼:

import java.util.concurrent.ArrayBlockingQueue; 
import java.util.concurrent.BlockingQueue; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class ProducerConsumerBlockingQueue { 

    public static void main(String[] args) { 
     Buffer buffer = new Buffer(); 

     ExecutorService executor = Executors.newFixedThreadPool(2); 
     executor.execute(new ProdBlock(buffer)); 
     executor.execute(new ConsBlock(buffer)); 
     executor.shutdown(); 
    } 

} 
class ProdBlock implements Runnable{ 

    Buffer buffer; 
    public ProdBlock(Buffer buffer) { 
     this.buffer = buffer; 
    } 

    public void run() { 
     for(int i = 1; i <= 10; i++){ 
      buffer.put(i); 
     } 

    } 

} 
class ConsBlock implements Runnable{ 

    Buffer buffer; 
    ConsBlock(Buffer buffer){ 
     this.buffer = buffer; 
    } 
    public void run() { 
     for(int i = 1; i <= 10; i++){ 
      buffer.get(); 
     }  
    } 

} 
class Buffer{ 
    int i; 
    BlockingQueue<Integer> sharedObject = new ArrayBlockingQueue<Integer>(1); 

    public void get(){ 
     try { 
      System.out.println("Getting - " + sharedObject.take()); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
    public void put(int i){ 
     this.i = i; 
     try { 
      sharedObject.put(i); 
      System.out.println("Putting - " + i); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

輸出:

Putting - 1 
Putting - 2 
Getting - 1 
Putting - 3 
Getting - 2 
Getting - 3 
Putting - 4 
Putting - 5 
Getting - 4 
Getting - 5 
Putting - 6 
Getting - 6 
Putting - 7 
Putting - 8 
Getting - 7 
Getting - 8 
Putting - 9 
Putting - 10 
Getting - 9 
Getting - 10 

Expectd輸出:

Putting - 1 
Getting - 1 
Putting - 2 
Getting - 2 
Putting - 3 
Getting - 3 
Putting - 4 
Getting - 4 
Putting - 5 
Getting - 5 
Putting - 6 
Getting - 6 
Putting - 7 
Getting - 7 
Putting - 8 
Getting - 8 
Putting - 9 
Getting - 9 
Putting - 10 
Getting - 10 

正如預期,阻塞隊列應一次僅取1值,它是如何存儲多個值?

+0

代碼步步 – Lucky

回答

1

它沒有存儲多個值。這只是一次取()方法返回,生產者可以將值添加到隊列中,而另一個線程打印之前打印的取值:

  1. 生產者線程:調用把(1) - 隊列有1元
  2. 生產線:打印「把1」 - 隊列中有1元
  3. 消費者線程:調用取() - 隊列爲空
  4. 生產者線程:調用把(2) - 隊列中有1個元素
  5. 生產者線程:打印「放置2」 - 隊列有1個元素
  6. 消費者線程:串聯字符串「獲得 - 」與步驟3中得到的整數1,並打印結果 - 隊列中有1元
+0

你說的「打印意味着調試它在另一個線程打印採取的值之前「?我通過'take()'方法獲取了值。如何在打印之前獲得價值? – Rohan

+0

看到我編輯的答案。 –

+0

感謝您的解釋。我明白了你的觀點。在這種情況下,是否無法打印正確的問題順序? – Rohan