A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黄克帅 中级黑马   /  2012-5-29 14:18  /  2255 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 黄克帅 于 2012-5-29 17:44 编辑

比老师视频上面讲的是 当true的时候 生产者就等待  ,当false的时候,消费者就等待。这样需要等待唤醒进行切换。  我改了下逻辑   改成当false的时候 生产者就生产  ,当true的时候 消费者就消费。  这样我不需要等待 唤醒切换,且不用while循环判断标签 貌似也可以实现功能,只是效率低点。 大家帮忙看看  代码有问题没。

毕老师原代码:
public class Resource {
        private String name;
        private int count = 1;
        private boolean flag = false;

        public synchronized void set(String name) {
                while (flag==true) {//每次唤醒都判断标签
                        try {
                                wait();//为true时  进入冻结状态 释放执行权
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }

                }
                this.name = name + "---" + count++;
               
                System.out.println(Thread.currentThread().getName() + "...生产者。。。"
                                + this.name);
                flag = true;
                this.notifyAll();//唤醒所有线程
        }

        public synchronized void out() {
                while (flag==false) {//每次唤醒都判断标签
                        try {
                                wait();//为false时  进入冻结状态 释放执行权
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                }
                System.out.println(Thread.currentThread().getName() + "...消费者。。。..."
                                + this.name);
                flag = false;
                this.notifyAll();//唤醒所有线程
        }
}


修改后代码
public class Resource {
        private String name;
        private int count = 1;
        private boolean flag = false;

        public synchronized void set(String name) {
                if(flag == false) {// 为false时生产
                        this.name = name + "---" + count++;
                        System.out.println(Thread.currentThread().getName() + "...生产者。。。"
                                        + this.name);
                        flag = true;
                }
        }

        public synchronized void out() {
                if(flag == true) {// 为true时消费
                        System.out.println(Thread.currentThread().getName()
                                        + "...消费者。。。..." + this.name);
                        flag = false;
                }
        }
}


以下不变
public class Prodoucer implements Runnable {
        private Resource res;
        public Prodoucer(Resource res) {
               
                this.res = res;
        }
        public void run() {
                while(true){
                        res.set("+商品+");
                }
               
        }

}

public class Consumer implements Runnable {
        private Resource res;
        public Consumer(Resource res) {
               
                this.res = res;
        }
        public void run() {
                while(true){
                        res.out();
                }
               
        }

}

public class Test {
        public static void main(String[] args) {
                Resource r = new Resource();
                Prodoucer pro = new Prodoucer(r);
                Consumer con = new Consumer(r);
                Thread t1 = new Thread(pro);
                Thread t2 = new Thread(con);
                Thread t3 = new Thread(pro);
                Thread t4 = new Thread(con);
               
                t1.start();
                t2.start();
                t3.start();
                t4.start();
               
        }
}

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

2 个回复

正序浏览
效率很低的这样,之所以有等待唤醒机制就是为了避免这种CPU资源的浪费。
为了说清道理,我们用“图书馆借书”这个经典例子来作解释。
    一本书同时只能借给一个人。现在有一本书,图书馆已经把这本书借了张三。
    在简单的synchrnozed 同步机制下,李四如果想借,先要去图书馆查看书有没有还回来。李四是个心急的人,他每天都去图书馆查;而张三看书看得慢,过了半个月才把书还回来,结果李四在这半个月里全都白跑了,浪费了不少交通车费 。
    而如果使用wait/notify机制,李四就不用白忙了。他第一次去图书馆时发现书已借走,就回家静静等待(wait);张三把书还掉后,通知(notify)李四,李四去图书馆拿书即可。整个过程中,李四没有白跑,没浪费钱。

回到计算机世界:
           书           --  临界资源,需互斥地访问
    张三,李四      --  两个竞争的线程
坐车去图书馆查书   --  轮询
      车费          --  CPU空间
      等待          --  wait
  通知下一个借书者   --  notify

    也就是说,若使用简单的synchonized机制实现互斥,会导致线程主动发起轮询,若N次轮询没有成功,就产生了N次的CPU空间浪费;如果加上了 wait/notify机制,就可以避免这些无谓的轮询,节省CPU的消耗。

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1 赞一个!

查看全部评分

回复 使用道具 举报
http://bbs.itheima.com/thread-14570-1-1.html
这是我之前发过的一个贴子,希望对你有帮助
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马