黑马程序员技术交流社区

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

作者: jk7130866    时间: 2015-7-25 11:18
标题: 多线程的同步、通讯
多线程的出现让我们的程序可以同时做不同的事情,但是伴随而来了一些问题。我们思考一下把线程比作是人,现在有两个线程,一个A线程能做饭,一个B线程能吃饭。他们同时开始,A开始做饭,做饭有哪些工作呢,简单一点就淘米,蒸米把。B呢就盛饭,吃饭。想象一下,A正在做饭,还在淘米,B来了,开始吃饭,正能行吗?饭还没好呢就吃了吗?多线程是不是有着的情况呢。来试验一下,创建饭模型
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(){
                taomi();//调用淘米步骤
                zhengmi();//调用蒸米
               
        }
        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(){
                chengfan();//调用盛饭步骤
                chifan();//调用吃饭
        }
        private void chengfan(){
                System.out.println(attr+"....."+"盛好了");
               
        }
        private void chifan(){
                System.out.println(attr+"....."+"吃完了");
                attr="生的";//吃完了饭的属性又回到生的
               
        }
                       
}

创建做饭模型他可以被子线程执行,实现Runnable接口

class Zuofan implements Runnable{//做饭线程
        Fan fan;
public         Zuofan(Fan fan){//创建对象是传入饭对象一面实现做饭功能
        this.fan=fan;
}
        @Override
        public void run() {
                //while(true)
                fan.cook();//调用饭的做饭功能
               
        }
}
创建吃饭模型他可以被子线程执行,实现Runnable接口

class Chifan implements Runnable{//吃饭线程
        Fan fan;
        public         Chifan(Fan fan){//创建对象是传入饭对象一面实现吃饭功能
                this.fan=fan;
        }
        @Override
        public void run() {
                //while(true)
                fan.eat();
                }

}
完成主函数,获得饭对象,启动两个子线程分别做饭吃饭吧,看看结果。
public class ThreadDem01 {

        public static void main(String[] args) {
                                Fan fan=Fan.getingstane();//获得饭对象
                                Zuofan zuofan=new Zuofan(fan);
                                Chifan chifan=new Chifan(fan);
                                new Thread(zuofan).start();
                                new Thread(chifan).start();

        }

}

结果如下:
淘米........生的
生的.....盛好了
蒸米........生的
生的.....吃完了
做好了........熟了

是不是乱了,米还是生的就盛饭了,还没有熟就吃完了,是不是合理。应该做饭完成再吃饭吧,怎么保证做饭的时候,你不能来吃呢。java是可以保证的,那就是线程同步,怎么来同步。java提供了同步代码块和同步函数两种方式。使用synchronized关键字我们来改进一下程序格式如下:
synchronized (对象) {
                语句块
                                }


原理是语句synchronized代码快持有一个对象作为锁,吃一样锁的线程可以执行,块内的语句,其它线程进不来,直到线程执行完语句块内的代码,释放了锁,线程才有可能进来。把下面的这两出修改一下,锁对象要相同,这里用单例,也可以是任何对象,比如Fan.class文件看看结果
synchronized (fan) {
               
                        chengfan();
                        chifan();
                }
synchronized (fan) {
                       
                        taomi();
                        zhengmi();
                }

运行结果:
淘米........生的
蒸米........生的
做好了........熟了
熟了.....盛好了
熟了.....吃完了

成了了吧,做完饭才可一吃,其实还是有问题的,也许吃饭线程先执行呢!!!就变成了吃完饭才做饭吧,如果让这两个线程无限循环,也许会吃完了再吃,做饭线程抢不到执行权对不对,这就涉及到多线程的通讯了,等会再说,先看看,同步的另一种方式,同步函数,其实原理相同也是持有锁对象,格式像这样在函数名前面家synchronized关键字就OK了,他持有的是this对象
public synchronized  void cook(){
                                taomi();
                        zhengmi();
                }
               
        }
现在来考虑刚才提到的线程通讯问题再,让这两个线程无限循环,这里就不贴出代码了,很简单,直接看结果吧!
淘米........生的
蒸米........生的
做好了........熟了
淘米........生的
蒸米........生的
做好了........熟了
淘米........生的
蒸米........生的
做好了........熟了
熟了.....盛好了
熟了.....吃完了

这里出现问题,但贴自字数限制在下帖子里不充完整。






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