初学者Thread线程问题,着急ing

时间:2008-01-16 12:58:01  来源:  作者:

下面是参考书上的一个“生产者-消费者”同步程序:

//主程序
public class ConProd {
public static void main(String args[]) {
Buffer buffer=new Buffer();
new Thread(new Producer(buffer)).start();
new Thread(new Consumer(buffer)).start();
}
}

//临界资源
class Buffer{
int data;
boolean dataready=false;

public synchronized int get(){
if (dataready==false){
try{
wait();
}
catch(InterruptedException e){}
}
dataready=false;
notify();
return data;
}

public synchronized void put(int i){
if(dataready==true){
try{
wait();
}catch(InterruptedException e){}
}
data=i;
dataready=true;
notify();
}
}

//生产者
class Producer implements Runnable{
Buffer buffer;
public Producer (Buffer buffer){
this.buffer=buffer;
}
public void run(){
int i;
while(true){
try{
Thread.sleep((int)Math.random()*1000);
}catch(InterruptedException e){}
i=(int)(Math.random()*100);
buffer.put(i);
System.out.println(i+" produced.");
}
}
}

//消费者
class Consumer implements Runnable{
Buffer buffer;
public Consumer (Buffer buffer){
this.buffer=buffer;
}
public void run(){
while(true){
try{
Thread.sleep((int)Math.random()*1000);
}
catch(InterruptedException e){}
System.out.println(buffer.get() +" consumed.");
}
}
}

上面程序运行结果应该是一个生产一个消费交替,例如:
3 produced.
3 consumed.
0 produced.
0 consumed.
...
但实际结果却往往是先产生两个产品,才开始消费,如下:
3 produced.
57 produced.
3 consumed.
0 produced.
57 consumed.
99 produced.
0 consumed.
...
不知道为什么会出现这种情况呢?刚学java不久,百思不得其解,请大家帮忙解释一下。 :?:



 ilcj 回复于:2004-09-05 19:40:51

的确是不确定的 顺序取决于你的操作系统和线程规划器!


 perryhg 回复于:2004-09-09 15:02:14

这是一个典型的线程同步问题,其实很好理解,对Producer来说,生产的过程有2个步骤
buffer.put(i);
System.out.println(i+" produced.");

对Consumer来说,消费也是2个步骤
buffer.get();
System.out.println(...+" consumed.");
尽管被写再一行里面,但是对于jvm来说,还是2件事情。

而你的Buffer的控制,只对get和put有效,也就是说,当你println的时候,buffer已经在做下一轮的get和put了,所以看起来好像控制会失效,其实还是有效的。要让这两个步骤绑定在一起,解决的办法是用synchronized块

        synchronized(buffer)

            {
                buffer.put(i);
                System.out.println(i+" produced.");
            }

            synchronized(buffer){
                System.out.println(buffer.get() +" consumed.");
            }





原文链接:http://bbs.chinaunix.net/viewthread.php?tid=400953
转载请注明作者名及原文出处


文章评论

共有 位网友发表了评论 查看完整内容