java多线程

来源:互联网 发布:阮一峰javascript 算法 编辑:程序博客网 时间:2024/05/20 10:22

java多线程之间的通讯(等待和唤醒机制)


代码1:

/***@author StormMaybin*@Date 2016-05-16*@<description>线程之间的通讯(等待唤醒机制)</description>*/class Res{    String name;    String sex;}class Input implements Runnable{    private Res r;    Input (Res r)    {        this.r = r;    }    public void run()    {        int x  = 0;        while (true)        {            synchronized (Input.class)            {                if (x == 0)                {                    r.name = "mike";                    r.sex = "nan";                }                else                {                    r.name = "mary";                    r.sex = "女";                }                x = (x + 1) % 2;            }        }    }}class Output implements Runnable{    private Res r;    Output (Res r)    {        this.r = r;    }    public void run ()    {        while (true)        {            synchronized (Input.class)            {                System.out.println (r.name+"..."+r.sex);            }        }    }}class  InputOutputTest{    public static void main(String[] args)     {        //System.out.println("Hello World!");        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();    }}

==这个代码是一个有问题的代码,为什么呢?因为在控制输入的线程输入了性别或者姓名的时候,此时,控制输出的线程抢到cpu的执行权,打印了性别或者是姓名,但是这个姓名和性别不一定是匹配的!所以问题就出在这了!==


代码2:

class Res{    String name;    String sex;    boolean flag = false;}class Input implements Runnable{    private Res r;    Input (Res r)    {        this.r = r;    }    public void run()    {        int x  = 0;        while (true)        {            synchronized (r)            {                if (r.flag)                {                    try                    {                        r.wait();                    }                    catch (Exception e)                    {                    }                }                if (x == 0)                {                    r.name = "mike";                    r.sex = "nan";                }                else                {                    r.name = "mary";                    r.sex = "女";                }                x = (x + 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 (r.name+"..."+r.sex);                r.flag = false;                r.notify();            }        }    }}class  InputOutputTest{    public static void main(String[] args)     {        //System.out.println("Hello World!");        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类中。

1 0