2015-09-11 53 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来修复它。