2015-09-11 90 views
-2

我在下面的代碼中收到錯誤。有人能幫我嗎?生產者消費者沒有同步程序時出錯

class Q 
    { 
     int n; 
     synchronized int get() 
     { 
      System.out.println("Got n :"+n); 
      return n; 
     } 
     synchronized void put(int n) 
     { 
      this.n = n; 
      System.out.println("Put n :"+n); 
     } 
    } 

class Producer implements Runnable 
{ 
    Q q1; 
    Producer(Q q) 
    { 
     this.q1 = q; 
     new Thread(this).start(); 
    } 
    public void run() 
    { 
     int i =0; 
     q1.put(i++); 
    } 
} 

class Consumer implements Runnable 
{ 
    Q q1; 
    Consumer(Q q) 
    { 
     this.q1 = q; 
     new Thread(this).start(); 
    } 
    public void run() 
    { 
     q1.get(); 
    } 
} 

class ProducerConsumerWithoutSync 
{ 
    public static void main(String args[]) 
    { 
     Q q = new Q(); 
     new Producer(q); 
     new Consumer(q); 
    } 
} 
+2

什麼是錯誤信息? – Jens

+1

永遠不要告訴其他程序員,你不知道錯誤是什麼,你會得到一個錯誤! –

+0

ProducerConsumerWithoutSync.java:7:缺少返回語句 } ^ 1錯誤 –

回答

0

不知道你怎麼了。我將你的代碼移植到ideone。 https://ideone.com/HdA0sP

正如你所看到的,它完美的工作。如果你認爲這個值應該是1,那麼你錯了。

您正在做q1.put(i++);此代碼返回i,然後向其中添加一個。如果你想在加1後返回數值,你應該使用++i

0

關於設計Q;
同步在Q完成,有一個假設; put將在get之前調用。但只有你的代碼保證的是; run方法Producer會先運行。

想象一下,Producer中的計算量很大(在調用put之前應該完成的事情),更可能會先調用get

我認爲它的可能性很低,但在目前的情況下,仍然可能發生。

這是生產者的run(假設你修正了凱文提到的++i);
> javap -c Producer

public void run(); 
    Code: 
     0: iconst_0  
     1: istore_1  
     2: aload_0  
     3: getfield  #15     // Field q1:LQ; 
     6: iinc   1, 1 
     9: iload_1  
     10: invokevirtual #31     // Method Q.put:(I)V 
     13: return   
} 

這是消費者的run方法;

public void run(); 
    Code: 
     0: aload_0  
     1: getfield  #15     // Field q1:LQ; 
     4: invokevirtual #31     // Method Q.get:()I 
     7: pop   
     8: return 

如您所見,在Q.get/set被調用之前有些事情要做。

您可以在get中使用wait,在put中使用notifyAll來修復它。