您的位置:首页 > 职场人生

黑马程序员-多线程--线程间的通信

2015-07-22 19:41 585 查看
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

线程间的通讯:

其实就是多个线程在操作同一个资源。

但是操作动作不同

 

例子:

需求:模拟简单卖票系统(输入一个人,紧接着输出一个人)

 

[java] view
plaincopy

class Res  

{  

    String name;  

    String sex;  

}  

class Input  implements Runnable  

{  

    private Res r;  

    private int t=0;  

    Input(Res r)  

    {  

        this.r=r;  

    }  

    public void run()  

    {  

        while(true)  

        {  

            if(t==1)  

            {  

                r.name="nike";  

                r.sex="man";  

            }  

            else   

            {  

                r.name="丽丽";  

                r.sex="女女";  

            }  

            t=(t+1)%2;  

        }  

    }  

}  

class Output  implements Runnable  

{  

    private Res r;  

    Output(Res r)  

    {  

        this.r=r;  

    }  

    public void run()  

    {  

        while(true)  

        {  

            System.out.println("output....."+r.name+"+++"+r.sex);  

        }  

    }  

}  

class InputOutputDemo  

{  

    public static void main(String[] args)  

    {  

        Res r=new Res();  

        Input in=new Input(r);  

        Output out=new Output(r);  

        Thread t1=new Thread(in);  

        Thread t2=new Thread(out);  

        t1.start();  

        t2.start();  

    }  

}  



出现了安全问题(输出了丽丽  MAN)

 

同步后

[java] view
plaincopy

class Res  

{  

    String name;  

    String sex;  

}  

class Input  implements Runnable  

{  

    private Res r;  

    private int t=0;  

    Input(Res r)  

    {  

        this.r=r;  

    }  

    public void run()  

    {  

        while(true)  

        {  

            synchronized(Res.class)  

            {  

                if(t==1)  

                {  

                    r.name="nike";  

                    r.sex="man";  

                }  

                else   

                {  

                    r.name="丽丽";  

                    r.sex="女女";  

                }  

                t=(t+1)%2;  

            }  

        }  

    }  

}  

class Output  implements Runnable  

{  

    private Res r;  

    Output(Res r)  

    {  

        this.r=r;  

    }  

    public void run()  

    {  

        while(true)  

        {  

            synchronized(Res.class)  

            {  

                System.out.println("output....."+r.name+"+++"+r.sex);  

            }  

        }  

    }  

}  

class InputOutputDemo2  

{  

    public static void main(String[] args)  

    {  

        Res r=new Res();  

        Input in=new Input(r);  

        Output out=new Output(r);  

        Thread t1=new Thread(in);  

        Thread t2=new Thread(out);  

        t1.start();  

        t2.start();  

    }  

}  



虽然安全 问题解决了,但并没出现我们想要的一男一女交替的情景

 

 

这是就引进一种方法:等待唤醒机制

 

[java] view
plaincopy

class Res  

{  

    String name;  

    String sex;  

    boolean flag;  

}  

class Input  implements Runnable  

{  

    private Res r;  

    private int t=0;  

    Input(Res r)  

    {  

        this.r=r;  

    }  

    public void run()  

    {  

        while(true)  

        {  

            synchronized(r)  

            {  

                if(r.flag)  

                    try{r.wait();}catch(Exception e){}  

                if(t==1)  

                {  

                    r.name="nike";  

                    r.sex="man";  

                }  

                else   

                {  

                    r.name="丽丽";  

                    r.sex="女女";  

                }  

                t=(t+1)%2;  

                r.flag=true;  

                r.notify();  

            }  

        }  

    }  

}  

class Output  implements Runnable  

{  

    private Res r;  

    Output(Res r)  

    {  

        this.r=r;  

    }  

    public void run()  

    {  

        while(true)  

        {  

            synchronized(r)  

            {  

                if(!r.flag)  

                    try{r.wait();}catch(Exception e){}  

                System.out.println("output....."+r.name+"+++"+r.sex);  

                r.flag=false;  

                r.notify();  

            }  

        }  

    }  

}  

class InputOutputDemo3  

{  

    public static void main(String[] args)  

    {  

        Res r=new Res();  

        Input in=new Input(r);  

        Output out=new Output(r);  

        Thread t1=new Thread(in);  

        Thread t2=new Thread(out);  

        t1.start();  

        t2.start();  

    }  

}  



 

 

wait:

notify();

notifyAll();

都使用在同步中,因为要对持有监视器(锁)的操作。

所以要使用在同步中,因为只有同步才具有锁。

为什么这些操作线程的凤飞飞要定义Object类中呢?

因为这些方法在操作同步中线程时,都必须要标识它们所操作线程中的锁,

只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒。

不可以被不同锁中的线程进行唤醒。

也就是说,等待和唤醒必须是同一个锁。

而锁可以是任意对象,所以可以被任意对象调用的方法定义Object类中。

 

 

下面进行代码改良:

[java] view
plaincopy

class Res  

{  

    private String name;  

    private String sex;  

    private boolean flag;  

    public synchronized void  set(String name,String sex)  

    {  

        if(this.flag)  

          try{this.wait();}catch(Exception e){}  

  

        this.name=name;  

        this.sex=sex;  

  

        this.flag=true;  

          this.notify();  

  

    }  

    public synchronized void out()  

    {  

        if(!this.flag)  

         try{this.wait();}catch(Exception e){}  

        System.out.println("output....."+this.name+"+++"+this.sex);  

        this.flag=false;  

                this.notify();  

    }  

}  

class Input  implements Runnable  

{  

    private Res r;  

    private int t=0;  

    Input(Res r)  

    {  

        this.r=r;  

    }  

    public void run()  

    {  

        while(true)  

        {  

            synchronized(r)  

            {  

                if(t==1)  

                    r.set("nike","man");  

                else   

                    r.set("丽丽","女女女");  

                t=(t+1)%2;  

            }  

        }  

    }  

}  

class Output  implements Runnable  

{  

    private Res r;  

    Output(Res r)  

    {  

        this.r=r;  

    }  

    public void run()  

    {  

        while(true)  

        {  

            synchronized(r)  

            {  

                r.out();  

            }  

        }  

    }  

}  

class InputOutputDemo4  

{  

    public static void main(String[] args)  

    {  

        Res r=new Res();  

        new Thread(new Input(r)).start();  

        new Thread(new Output(r)).start();  

        /* 

        Input in=new Input(r); 

        Output out=new Output(r); 

        Thread t1=new Thread(in); 

        Thread t2=new Thread(out); 

        t1.start(); 

        t2.start(); 

        */  

    }  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: