object的notify、wait对线程使用的理解

    xiaoxiao2021-03-25  123

         在线程中,notify--会唤醒一个等待线程、wait --会使当前线程进入等待状态,但是这两个方法都是属于Object类的,也就是对象调用。在我们平时使用时,大多直接使用this来替代当前对象,这样我们在理解时,我认为this代表的是当前线程对象,而一个线程对象对他的当前线程进行操作,是一个很正常的事,

    看一个例子:

    tes类有3个属性

    public class Tes { String A="a"; String B="b"; String C="c"; }

    Mythread 类为线程类

    public class Mythread implements Runnable{ private Object o1; private Object o2; private int i=100; @Override public void run() { while(i>0){ synchronized (o1) { synchronized (o2) { System.out.println(i--+"-"+o1+"-"+Thread.currentThread().getName()); o2.notify(); } try { o1.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }

    运行,创建 3个线程对象,3个对象的成员都使用同一份资源,t

    public static void main(String[] args) { Tes t=new Tes(); Mythread m1=new Mythread(t.A,t.B); Mythread m2=new Mythread(t.B,t.C); Mythread m3=new Mythread(t.C,t.A); Thread th1=new Thread(m1); Thread th2=new Thread(m2); Thread th3=new Thread(m3); th1.start(); th2.start(); th3.start(); }

    运行结果

        a线程先进去会占用A,B两个资源,b、c两个线程会由于a线程的占用会暂时等待直到a线程释放锁,同时a线程进入等待状态直到b或者c线程唤醒a线程;

       接下来将3条线程改为2条线程

     

    public static void main(String[] args) { Tes t=new Tes(); Mythread m1=new Mythread(t.A,t.B); Mythread m2=new Mythread(t.B,t.C); // Mythread m3=new Mythread(t.C,t.A); Thread th1=new Thread(m1); Thread th2=new Thread(m2); // Thread th3=new Thread(m3); th1.start(); th2.start(); // th3.start(); }

    运行结果:

       只有两个线程时会发现a,b线程都进入到等待状态,为什么a线程先进入等地状态,b线程无法唤醒它?

      再来看wait, notify。wait会使当前线程进入等待,同时释放锁,notify会唤醒此对象的一条等待线程,a线程是由 A调用wait进入等待,那么也就应该由 A来唤醒,所以b线程中的唤醒是 C的线程,也就无法唤醒a线程,b线程也是因为没有B的notify调用,而无法唤醒。

    转载请注明原文地址: https://ju.6miu.com/read-6265.html

    最新回复(0)