jvm的线程之间的通信-notify-wait-notifyAll

一、超类 Object 使用 native code 实现的 线程之间的 通信是怎样的?

二、源码注解

       notify 1)这个线程 正在 等待 对象的监视器 2)被唤醒 

      wait    (1) 这个线程等待  2)直到被通知 程序抛错

      notifyAll 1)一组线程正在 等待 对象的监视器 2)都被唤醒

/**

 *

 */

public class NotifyTest {


  public static class NotifyThread extends Thread{

    public NotifyThread( String name , Runnable runnable ){

       super( runnable, name );

    }


  }


  public static class NotifyAllThread extends Thread{

    public NotifyAllThread( String name , Runnable runnable ){

      super( runnable,name);

    }

  }


  public static class WaitThread extends Thread{

    public WaitThread( String name , Runnable runnable ){

      super( runnable,name);

    }

  }

  public static class RunableSyncTest implements Runnable{


    @Override

    public void run() {

      synchronized ( this ){

        try {

          System.out.println(" thread is waiting before :"+ Thread.currentThread().getName() );

          super.wait();

          System.out.println(" thread is waiting after "+ Thread.currentThread().getName() );

        } catch (InterruptedException e) {

          e.printStackTrace();

        }

      }

    }

  }


  public static void main(String[] args) {

    Runnable runnable = new RunableSyncTest();

    NotifyAllThread allThread = new NotifyAllThread("all", runnable);

    NotifyThread notifyThread = new NotifyThread("notify", runnable);

    WaitThread waitThread = new WaitThread("wait", runnable);

    allThread.start();

    notifyThread.start();

    waitThread.start();

  }

}



代码结果

  /***

 thread is waiting before :all

 thread is waiting before :notify # 加锁了,为什么 这个线程进来了?   

 thread is waiting before :wait # 为什么没有继续向下执行?

  ***/

先看测试代码(知道的浅,只能从Java 代码级别发生的情况确定,牛人看c

1wait() 等待的表现是?释放了当前的锁,进入 线程等待队列,直到被这个队列的某一个线程通知,才能继续获得锁。

2、三个线程一直都处于等待中,没有谁来通知。

3、一定得是 当前对象的锁,才能调用当前对象的wait(),notify(),notifyAll();  

在这里 加锁 的对象是 this ,  调用的是 this.wait(); 官方的要求是:只有获得对象的监视器,才能有“料”,去 wait(),去 通知


package notify;


import java.util.concurrent.atomic.AtomicInteger;


/**

 * 

 */

public class NotifyTest {


  public static class NotifyThread extends Thread{

    public NotifyThread( String name , Runnable runnable ){

       super( runnable, name );

    }


  }


  public static class NotifyAllThread extends Thread{

    public NotifyAllThread( String name , Runnable runnable ){

      super( runnable,name);

    }

  }


  public static class WaitThread extends Thread{

    public WaitThread( String name , Runnable runnable ){

      super( runnable,name);

    }

  }



  public static class RunableSyncTest implements Runnable{


    AtomicInteger integer = new AtomicInteger(0);


    @Override

    public void run() {

      synchronized ( this ){

        try {

          System.out.println("before :["+ Thread.currentThread().getName()+"]  count:"+ integer.addAndGet( 1 ) );

          if( integer.get() % 2 > 0 ){

             super.wait();

             System.out.println("waiting ["+ Thread.currentThread().getName()+"]" );

          }else{

             super.notify();

             System.out.println("go to notify ["+ Thread.currentThread().getName()+"]" );

          }

          System.out.println("after:  [ "+Thread.currentThread().getName()+"]" );

        } catch (InterruptedException e) {

          e.printStackTrace();

        }

      }

    }

  }


  public static void main(String[] args) {

    Runnable runnable = new RunableSyncTest();

    NotifyAllThread allThread = new NotifyAllThread("all", runnable);

    NotifyThread notifyThread = new NotifyThread("notify", runnable);

    WaitThread waitThread = new WaitThread("wait", runnable);

    allThread.start();

    notifyThread.start();

    waitThread.start();

  }

}


# 代码运行结果 

before :[all]  count:1 # all先获得锁

before :[wait]  count:2 # all进入等待队列,释放了锁,

go to notify [wait]  # wait线程抢到了锁,开始通知

after:  [ wait] #

before :[notify]  count:3 

finally [all]

waiting [all]

after:  [ all]

finally [notify]

waiting [notify]

after:  [ notify]


总结:

  1)要想 使用 wait()\notify()这些方法,先得获取使用该对象的 监控器(锁),得加锁。

  2wait(),使线程放弃锁,在原地进行了等待(应该是进入了 竞争该监控器的等待队列),被唤醒后,从原地开始执行(thread有自己的程序计数器)

  3notify() | notifyAll()  当前拥有对象监控器的 开始释放锁,通知 等待队列

应用场合

1)例如: netty 生成异步结果代码段,说是异步转同步,本质的该线程一直在等待结果,拿到结果后才返回。

 @Override

    public Promise<V> await() throws InterruptedException {

        if (isDone()) {

            return this;

        }

        if (Thread.interrupted()) {

            throw new InterruptedException(toString());

        }

        checkDeadLock();

        synchronized(this) { ## this 进行加锁

            while (!isDone()) { ## 结果还没有 完成

                incWaiters(); ## 增加等待线程数;

                try {

                    wait(); ## 该线程进入等待队列,(阻塞了)释放锁,另外一个线程进入

                } finally {

                    decWaiters();## 被通知了,出队列,

                }

            }

        }

        return this;

    }


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值