java笔记--线程间通信

线程间通讯:

多个线程在处理同一资源,但是任务却不同 。

比如对于同一个资源,一边在输入,一边在输出:

class Resource{
    String name;
    String sex;
}
//输入
class Input implements Runnable{
    Resource r;
    Input(Resource r){
        this.r=r;
    }
    public void run(){
        int x=0;
        while(true){
            synchronized(r){//因为Resource是共同操作的,所以r可以作为锁
                if(x==0){
                    r.name="mike";
                    r.sex="nan";
                }else{
                    r.name="丽丽";
                    r.sex="女女女女";
                }
                x=(x+1)%2;
            }
        }
    }
}
//输出
class Output implements Runnable{
    Resource r;
    Output(Resource r){
        this.r=r;
    }
    public void run(){
        while(true){
            synchronized(r){
                System.out.print(r.name+"..."+r.sex);
            }
        }
    }
}

public class TongXun {

    public static void main(String[] args) {
        //创建资源
        Resource r=new Resource();
        //创建任务
        Input in=new Input(r);
        Output out=new Output(r);
        //创建线程,执行路径
        Thread t1=new Thread(in);
        Thread t2=new Thread(out);
        //开启线程
        t1.start();
        t2.start();
    }
}

运行:

等待唤醒机制:

涉及的方法:

1 wait():让线程处于冻结状态,被wait的线程会被存储到线程池当中。
2 notify():唤醒线程池中的任意一个线程。
3 notifyAll():唤醒线程池中的所有线程

这些方法都必须定义在同步中。
因为这些方法是用于操作线程状态的方法。
必须要明确到底操作得是哪个锁上的线程。

class Resource{
    String name;
    String sex;
    boolean flag=false;
}
//输入
class Input implements Runnable{
    Resource r;
    Input(Resource r){
        this.r=r;
    }
    public void run(){
        int x=0;
        while(true){
            synchronized(r){//因为Resource是共同操作的,所以r可以作为锁
                if(r.flag)
                    try{
                        r.wait();
                        }catch(InterruptedException e){ 
                        }
                if(x==0){
                    r.name="mike";
                    r.sex="nan";
                }else{
                    r.name="丽丽";
                    r.sex="女女女女";
                }
                r.flag=true;
                r.notify();
            }
            x=(x+1)%2;
        }
    }
}
//输出
class Output implements Runnable{
    Resource r;
    Output(Resource r){
        this.r=r;
    }
    public void run(){
        while(true){
            synchronized(r){
                if(!r.flag)
                    try{
                        r.wait();
                        }catch(InterruptedException e){ 
                        }
                System.out.println(r.name+"..."+r.sex);
                r.flag=false;
                r.notify();
            }
        }
    }
}
public class NofityDemo {

    public static void main(String[] args) {
        //创建资源
        Resource r=new Resource();
        //创建任务
        Input in=new Input(r);
        Output out=new Output(r);
        //创建线程,执行路径
        Thread t1=new Thread(in);
        Thread t2=new Thread(out);
        //开启线程
        t1.start();
        t2.start();
    }
}

运行:

等待唤醒机制避免了成片的输出的现象,因为等待唤醒机制做的就是当一个资源被输入,资源被占有,只有先输出了才能再次输入资源

思考1:wait(),notify(),notifyAll(),用来操作线程为什么定义在了Object类中?
1 这些方法存在于同步中;
2 使用这些方法时必须要标识所属的同步的锁。
3 锁可以是任意对象,所以任意对象调用的方法一定定义在Object类中。

优化:

资源一般都是私有的,这里资源进行私有化,并对外提供方法。

class Resource{
    private String name;
    private String sex;
    private boolean flag=false;
    
    public synchronized void set(String name,String sex){
        if(flag)
            try{
                this.wait();
                }catch(InterruptedException e){ 
                }
        this.name=name;
        this.sex=sex;
        flag=true;
        this.notify();
    }
    public synchronized void Out(){
        if(!flag)
            try{
                this.wait();
                }catch(InterruptedException e){ 
                }
        System.out.println(name+"...优化..."+sex);
        flag=true;
        this.notify();
    }
}
//输入
class Input implements Runnable{
    Resource r;
    Input(Resource r){
        this.r=r;
    }
    public void run(){
        int x=0;
        while(true){
            if(x==0){
                r.set("mike","nan");
            }else{
                r.set("mike","nan");
                }
            x=(x+1)%2;
            }
            
        }
    }
//输出
class Output implements Runnable{
    Resource r;
    Output(Resource r){
        this.r=r;
    }
    public void run(){
        while(true){
            r.Out();
        }
    }
}
public class NofityDemo {

    public static void main(String[] args) {
        //创建资源
        Resource r=new Resource();
        //创建任务
        Input in=new Input(r);
        Output out=new Output(r);
        //创建线程,执行路径
        Thread t1=new Thread(in);
        Thread t2=new Thread(out);
        //开启线程
        t1.start();
        t2.start();
    }
}

运行:

思考2:wait(),sleep()有什么区别?
wait()释放执行权,释放锁;sleep()释放cpu执行权,不释放锁。

你可能感兴趣的:(java笔记--线程间通信)