免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2592 | 回复: 2
打印 上一主题 下一主题

初学者Thread线程问题,着急ing [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-09-05 12:37 |只看该作者 |倒序浏览
下面是参考书上的一个“生产者-消费者”同步程序:

//主程序
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不久,百思不得其解,请大家帮忙解释一下。

论坛徽章:
0
2 [报告]
发表于 2004-09-05 19:40 |只看该作者

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

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

论坛徽章:
0
3 [报告]
发表于 2004-09-09 15:02 |只看该作者

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

这是一个典型的线程同步问题,其实很好理解,对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块

  1.         synchronized(buffer)
  2.             {
  3.                 buffer.put(i);
  4.                 System.out.println(i+" produced.");
  5.             }

  6.             synchronized(buffer){
  7.                 System.out.println(buffer.get() +" consumed.");
  8.             }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP