黑马程序员技术交流社区

标题: 多线程的同步、通讯2 [打印本页]

作者: jk7130866    时间: 2015-7-25 11:20
标题: 多线程的同步、通讯2

继续刚才的话题看到了吧做了好几此饭才吃了一次,这不合理吧,我们怎么让做一次饭吃一次饭,通讯的机制是锁对象的wait(),notify()机制l来实现一下吧,class Fan{
        private  Fan() {
                // TODO Auto-generated constructor stub
        }
        private static Fan fan=new Fan();//单例化 两个人做的做的同一件事
        public static Fan getingstane(){
                return fan;
        }
       
        private String attr="生的";//饭的属性方便演示
        public   void cook(){
                synchronized (fan) {
                        if("熟了".equals(attr))
                        {
                                try {
                                        fan.wait();
                                } catch (InterruptedException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                }
                        }
                               
                        taomi();
                        zhengmi();
                        fan.notify();
                }
               
        }
        private void taomi(){
                attr="生的";
                System.out.println("淘米"+"........"+attr);
               
        }
        private void zhengmi(){
                attr="生的";
                System.out.println("蒸米"+"........"+attr);
                try {
                        Thread.currentThread().sleep(10);//模拟蒸饭的时间
                } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
                attr="熟了";
                System.out.println("做好了"+"........"+attr);
               
               
        }
       
        public void eat(){
                synchronized (fan) {
                        if("生的".equals(attr)){
                                try {
                                        fan.wait();
                                } catch (InterruptedException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                }
                        }
                        chengfan();
                        chifan();
                       
                        fan.notify();
                }
        }
        private void chengfan(){
                System.out.println(attr+"....."+"盛好了");
               
        }
        private void chifan(){
                System.out.println(attr+"....."+"吃完了");
                attr="生的";//吃完了饭的属性又回到生的
               
        }
       
                       
}
红色的字体是修改的代码,简单实现了等待唤醒机制看看结果
淘米........生的
蒸米........生的
做好了........熟了
熟了.....盛好了
熟了.....吃完了
淘米........生的
蒸米........生的
做好了........熟了
熟了.....盛好了
熟了.....吃完了
淘米........生的
蒸米........生的
做好了........熟了
熟了.....盛好了
熟了.....吃完了
淘米........生的
蒸米........生的
做好了........熟了
熟了.....盛好了
熟了.....吃完了
淘米........生的
蒸米........生的
做好了........熟了
熟了.....盛好了
熟了.....吃完了看到了把做一次饭吃次饭,它的实现机制是什么,原理很简单,线程当一个线程持有一个锁对象,当锁对象吊用自己的wait()方法该线程冻结,比释放锁,让别的线程可以进来。所以这种方式只能用在同步当中哦!!掉用notify()方法可以唤醒线程池当中的了、第一个线程,这里只有两个线程,所以唤醒的一定是对方线程,保证下次一定会有两个识别不同表示的线程进入同步,以防全部冻结,程序进行执行不了。如果不知两个线程执行呢,我把线程这样分类,同样功能的线程成为本方线程,对应的执行另一个功能线程叫做对方线程。现在再两个线程看看把

                                new Thread(zuofan,"做饭线程1").start();
                                new Thread(zuofan,"做饭线程2").start();
                                new Thread(chifan,"吃饭线程1").start();
                                new Thread(chifan,"吃饭线程2").start();
加上线程的名字看的更清楚,看看结果
熟了.....盛好了吃饭线程2
熟了.....吃完了吃饭线程2
生的.....盛好了吃饭线程1
生的.....吃完了吃饭线程1
淘米........生的做饭线程2
蒸米........生的做饭线程2
做好了........熟了做饭线程2
熟了.....盛好了吃饭线程2
熟了.....吃完了吃饭线程2现在先来看看那刚才出现的情况吧这是怎么回事呢做么有乱了,分析一下,饭线程1准备吃饭发现饭是生的
if("生的".equals(attr)){

                                try {

                                        fan.wait();

                                } catch (InterruptedException e) {

                                        // TODO Auto-generated catch block

                                        e.printStackTrace();

                                }

                        }

chengfan();
        chifan();
                       
fan.notify();
                }
        }


挂在了这,做饭线程进来做好饭,接着吃饭吃饭线程2来了他吃完了,唤醒等待整的线程,这里是饭线程1他醒了取得锁,从挂起来的地方开始执行,还进行判断吗,if语句是执行完语句体就继续只、执行下面的语句也就是
chengfan();问题来了吧,这时候饭是生的的,没进行判断继续了,只要让他醒来就先判断自己该不该继续等带就行了,用whlie语句修改看看结果


蒸米........生的做饭线程1
做好了........熟了做饭线程1
熟了.....盛好了吃饭线程2
熟了.....吃完了吃饭线程2
淘米........生的做饭线程2
蒸米........生的做饭线程2
做好了........熟了做饭线程2
不乱了,但是怎么卡住了是这样的当对方线程都进入冻结,本方线程执行完,唤醒的还是本方线程那就挂了,怎么才能保证对方线程一定被唤醒呢,简单noyifyall();就Ok了;试试把,结果可行我就补贴出来了。








欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2