多线程间之间的通信

2018-07-09  本文已影响0人  东风谷123Liter
image.png
/*
需求:有一堆媒,有一卡车来拉煤,还有一卡车送煤来;
分析:煤堆就是一个对象;一辆卡车就是一个线程。

类似的:一个仓库,存放注册者的姓名和性别,分别有注册和输出两个线程。
*/
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){
            if(x == 0){
                r.name = "mike";
                r.sex = "man";
            }
            else{
                r.name = "Lily";
                r.sex = "woman";
            }
            x = (x+1)%2;
        }
    } 
}
class Output implements Runnable{
    private Res r ;
    Output(Res r){
        this.r = r;
    }
    public void run(){
        while(true){
            System.out.println(r.name+" "+r.sex);
        }
    } 
}
class InputOutputDemo{
    public static void main(String[] args){
        Res r = new Res();
        Input in = new Input(r);
        Output ou = new Output(r);

        Thread t1 = new Thread(in);
        Thread t2 = new Thread(ou);

        t1.start();
        t2.start();
    } 
}
/*
需求:有一堆媒,有一卡车来拉煤,还有一卡车送煤来;
分析:煤堆就是一个对象;一辆卡车就是一个线程。

类似的:一个仓库,存放注册者的姓名和性别,分别有注册和输出两个线程。
*/
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)  //之所以用Input.class作为对象,而没有用其他比如Object类对象,是因为保证两个线程使用的是同一个锁!
                if(x == 0){                       //其实这里用 r 比较合适,r也是唯一的。
                    r.name = "mike";
                    r.sex = "man";
                }
                else{
                    r.name = "Lily";
                    r.sex = "woman";
                }
                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 InputOutputDemo{
    public static void main(String[] args){
        Res r = new Res();
        Input in = new Input(r);
        Output ou = new Output(r);

        Thread t1 = new Thread(in);
        Thread t2 = new Thread(ou);

        t1.start();
        t2.start();
    } 
}

wait():

notiyf():

notiyfAll():唤醒全部线程。

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

   /*
需求:有一堆媒,有一卡车来拉煤,还有一卡车送煤来;
分析:煤堆就是一个对象;一辆卡车就是一个线程。

类似的:一个仓库,存放注册者的姓名和性别,分别有注册和输出两个线程。
*/
class Res{
    
    String name;
    String sex;
    boolean flag = false;    //设置flag来表示仓库里面有没有资源。
}
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)    //使用wait(),notify()交替执行,保证输入、输出两个线程交替执行,不会出现死锁的问题!
                    try{r.wait();} catch(Exception e){}    //wait()方法在Object类中,不在Thread()类中!Thread继承了Object类的。
                if(x == 0){
                    r.name = "mike";
                    r.sex = "man";
                }
                else{
                    r.name = "Lily";
                    r.sex = "woman";
                }
                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 InputOutputDemo{
    public static void main(String[] args){
        Res r = new Res();
        Input in = new Input(r);
        Output ou = new Output(r);

        Thread t1 = new Thread(in);
        Thread t2 = new Thread(ou);

        t1.start();
        t2.start();
    } 
}
class Res{     //set()和out()都是对本类对象。
    String name;
    String sex;
    boolean flag = false;
    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(this.name+" "+this.sex);
        this.flag = false;
        this.notify();
    }
}
class Input implements Runnable{
    private Res r;    //对象引用,不创建对象,对象由外面导入。
    Input(Res r){
        this.r = r;
    }
    public void run(){
        int x = 0;
        while(true){
            if(x == 0){
                r.set("mike","man");
            }
            else{
                r.set("Lily","woman");
            }
            x = (x+1)%2;
        }
    } 
}
class Output implements Runnable{
    private Res r ;
    Output(Res r){
        this.r = r;
    }
    public void run(){
        while(true){
            r.out();
        }
    } 
}
class InputOutputDemo1{
    public static void main(String[] args){
        Res r = new Res();
        new Thread(new Input(r)).start();    //线程对象都用匿名对象类创建对象,启动线程。
        new Thread(new Output(r)).start();
    } 
}
上一篇 下一篇

猜你喜欢

热点阅读