zoukankan      html  css  js  c++  java
  • 等待唤醒机制

    1、多个线程在处理同一个资源时,叫同步。多个线程可处理的动作相同,如:多个线程都执行买票操作,对票资源减少

    2、如果处理的动作不同,通过一定的手段使各个线程能有效的利用资源。而这种手段即—— 等待唤醒机制。

    如:一个执行买票操作,减少票资源,一个执行退票操作,增加票资源

    1、等待唤醒机制所涉及到的方法:

    定义在Object类中

    • wait() :等待,将正在执行的线程释放其执行资格 和 执行权,并存储到线程池中。
    • notify():唤醒,唤醒线程池中被wait()的线程,一次唤醒一个,而且是任意的。
    • notifyAll(): 唤醒全部:可以将线程池中的所有wait() 线程都唤醒。

    注意:这些方法都是同步中才有效。同时这些方法在使用时必须标明所属锁,这样才可以明确出这些方法操作的到底是哪个锁上的线程。

    2、实例介绍

    创建一个类Resource,包括name,sex两个属性

    input轮流传入两个个Resource对象,output轮流输出Resource对象属性

    注意问题:

    1、必须保证输入和输出为同一对象,如果输出为新建对象,输出为null

    解决方法:在测试类中创建对象,将对象分别传给输入输出两个线程,两个线程分别创建有参构造接收,保证为同一对象

    2、轮流数入的两个数据在输出时会发生混乱,不能保证数据的唯一性

    解决方法:添加同步锁(锁对象synchronized),保证线程的安全性问题

    3、数据不能轮流输出,因为为抢栈操作,所以不能保证轮流输出

    解决方法:用等待唤醒机制,添加wait()和notify()

    流程步骤

    输入线程向Resource中输入name ,sex , 输出线程从资源中输出,先要完成的任务是:

    1.当input发现Resource中没有数据时,开始输入,输入完成后,叫output来输出。如果发现有数据,就wait();

    2.当output发现Resource中没有数据时,就wait() ;当发现有数据时,就输出,然后,叫醒input来输入数据。

    代码展示

    创建类Resource

    public class Resource {
        public String name;
        public String sex;
    //定义一个标志,判断线程状态
        public boolean flag=false;
    
    }

    创建输入方法,继承Runnable

    public class Input implements Runnable{
    //定义Resource对象r
        private Resource r;
    //创建有参构造,接收r,并传给本类对象
        public Input(Resource r){
            this.r=r;
        }
    //定义int数,对2取余,实现轮流传入两个对象
        private int i=0;
    //重写run方法
        public void run() {
    //死循环,不断循环输入
            while(true){
    //同步代码块,多线程使用同一所对象,将r定义为锁对象
    //两个线程输入和输出,用同一对象
                synchronized (r) {
    //判断,如果标志flag为true,输入线程执行等待操作(默认为false)
                    if(r.flag==true){
                        try {
                            r.wait();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
    //如果标志flag为false,轮流给对象r赋值
                    if(i%2==0){
                        r.name="张三";
                        r.sex="男";
                    }else{
                        r.name="lisi";
                        r.sex="nv";
                    }
    //传入完成,将标志变为true
                    r.flag=true;
                    r.notify();//随机唤醒 wait()的线程
                }           
                i++;
            }
            
        }
    
    }

    创建输出方法,继承Runnable

    public class Output implements Runnable{
    //定义Resource对象r
        private Resource r;
    //创建有参构造,接收r,并传给本类对象
        public Output(Resource r){
            this.r=r;
        }
    //重写run方法
        public void run() {
            while(true){
                synchronized (r) {
    //如果标志位false,线程等待
                    if(!r.flag){
                        try {
                            r.wait();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
    //如果标志位true,输出对象r的内容
                    System.out.println(r.name+"..."+r.sex);
    //将标志变为false
                    r.flag=false;
                    r.notify();//随机唤醒 wait()的线程
                }            
                
            }
            
        }
    
    }

    测试类

    public class Test {
    
        public static void main(String[] args) {
            //新建唯一Resource实例
            Resource r=new Resource();
                     //创建Input实例
            Input in=new Input(r);
                     //创建Output实例
            Output out=new Output(r);
                     //创建输入线程
            Thread tin=new Thread(in);
                     //创建输出线程
            Thread tout=new Thread(out);
                  //运行线程
            tin.start();
            tout.start();
    
        }
    
    }
  • 相关阅读:
    2.22
    LG P7077 函数调用
    2020/10/30 模拟赛 序列
    2020/10/27 模拟赛 数列
    2020/10/23 模拟赛 chip
    2020/10/23 模拟赛 escape
    2020/10/23 模拟赛 center
    LOJ#6581. 「ICPC World Finals 2019」断头路探测者
    LG P1587 [NOI2016]循环之美
    LG P4156 [WC2016]论战捆竹竿
  • 原文地址:https://www.cnblogs.com/dk2557/p/9549551.html
Copyright © 2011-2022 走看看