美文网首页
java笔记--线程间通信

java笔记--线程间通信

作者: 吃饱喝足搬代码丶 | 来源:发表于2018-04-10 23:38 被阅读0次

    线程间通讯:

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

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

    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笔记--线程间通信

          本文链接:https://www.haomeiwen.com/subject/ktnwhftx.html