• 为什么wait()和notify()属于Object类


    关于wait()暂停的是持有锁的对象,所以想调用wait()必须为:对象.wait();

    notify()唤醒的是等待锁的对象,调用:对象.notify();

    如下:

    Object obj = newObject();

    synchronized(obj){

        try{  

          obj.wait();

          }catch(Exception e){}

          obj.notify();

      }

    注意:wait(),notify(),notifyAll()都必须使用在同步中,因为要对持有监视器(锁)的线程操作。所以要使用在同步中,因为只有同步 才具有锁。

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

    简单说:因为synchronized中的这把锁可以是任意对象,所以任意对象都可以调用wait()和notify();所以wait和notify属于Object。

    专业说:因为这些方法在操作同步线程时,都必须要标识它们操作线程的锁,只有同一个锁上的被等待线程,可以被同一个锁上的notify唤醒,不可以对不同锁中的线程进行唤醒。

    也就是说,等待和唤醒必须是同一个锁。而锁可以是任意对象,所以可以被任意对象调用的方法是定义在object类中。

    在jdk1.5以后,将同步synchronized替换成了Lock,将同步锁对象换成了Condition对象,并且Condition对象可以有多个,这样可以解决一个问题。

    比如说我们在多个生产者和消费者模式中:

    boolean flag = false;

    public synchronized void set(String name){

      while(flag){//用while而不用if的原因,这样每个线程在wait等待醒来后都必须再次判断flag

        try{this.wait();}catch(Exception e){}  

        Sytem.out.printLn("生产者");

        flag = true;

        this.notifyAll();//这将唤醒所有线程(本方线程和对方线程),消耗资源

      }

    }

    public synchronized void out(){

      whie(!flag){

         try{this.wait();}catch(Exception e){}

        Sytem.out.printLn("消费者");

        flag = false;

        this.notifyAll();//这将唤醒所有线程(本方线程和对方线程),消耗资源

      }

    }

    上面的做法很消耗资源,如果把notifyAll()改成notify()的话,就会造成可能所有线程都在等待

    所以在jdk1.5以后提供了Lock接口和Condition对象。Condition中的await(), signal().signalAll()代替Object中的wait(),notify(),notifyAll()

    private Lock lock = new ReentrantLock();

    private Condition condition_pro = lock.newCondition();//生产者对象

    private Condition condition_con = lock.newCondition();//消费者对象

    public void set(String name) throws Exception{

      lock.lock();//加锁

      try{

        while(flag){

         contion_pro.await();

         Sytem.out.printLn("生产者");

           flag= true;

         condition_con.singal();//指定唤醒消费方

       }finally{

        lock.unlock();//解锁    

        }  

      }

    }

    public void out() throws Exception{

      lock.lock();

      try{

        while(!flag){

           condition_con.await(); 

           Sytem.out.printLn("消费者");

           flag = false;

           condition_pro.signal();//指定唤醒生产方

          }finally{

          lock.unlock();  

          }

        }

    }

    这样做的好处,我们可以指定唤醒某一方,减少消耗

    Java小生店铺:

    Pc端:http://shop125970977.taobao.com/index.htm

    手机端:搜索 java小生店铺

    希望店铺的资料能帮助到你!!!

     

  • 相关阅读:
    centos 7:network: 正在打开接口 ens33: 错误:激活连接失败:No suitable device found for this connection.
    python 连接 hive 的 HiveServer2 的配置坑
    node的 node-sass@^4.11.0 出现:npm: no such file or directory, scandir '.../node_modules/node-sass/vendor'
    DX关联VS
    PIX
    英特尔® 图形性能分析器(Intel® GPA)
    C++之异常处理
    VS挂接崩溃包
    system 函数
    C++ Template
  • 原文地址:https://www.cnblogs.com/lirenzhujiu/p/5927241.html
Copyright © 2020-2023  润新知