java并发 --wait与notify原理

Posted Hepburn Yang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java并发 --wait与notify原理相关的知识,希望对你有一定的参考价值。

重量级锁通过对象内部的监视器(monitor)实现,其中monitor的本质是依赖于底层操作系统的Mutex Lock实
现,操作系统实现线程之间的切换需要从用户态到内核态的切换,切换成本非常高。前面我们在讲Java对象头的时候,讲到了monitor这个对象,在hotspot虚拟机中,通过ObjectMonitor类来实现monitor。他的锁的获取过程的体现会简单很多.

wait 和notify

wait和notify是用来让线程进入等待状态以及使得线程唤醒的两个操作
wait()必须被synchronized来使用,

public class ThreadWait extends Thread
private Object lock;
public ThreadWait(Object lock) 
   this.lock = lock;
 

@Override
public void run() 
	
	synchronized (lock)
	System.out.println("开始执行 thread wait");
	
	try 
	lock.wait();
	    catch (InterruptedException e) 
	e.printStackTrace();
	    
	   System.out.println("执行结束 thread wait");
	
 

public class ThreadNotify(Object lock) 
  this.lock = lock;
 

@Override
public void run() 
	synchronized (lock)
		System.out.println("开始执行 thread notify");
		lock.notify();
		System.out.println("执行结束 thread notify");
	
  

wait 和notify的原理

  1. 调用wait() 首先会获取监视器锁,获得成功后,会让线程进入等待状态进入等待队列并且释放锁;
  2. 然后当其他线程调用notify或者notifyall以后,会选择从等待队列中唤醒任意一个线程
  3. 而执行完notify方法以后,并不会立马唤醒线程,原因是当前线程仍然持有这把锁,处于等待状态的线程无法获得锁。必须要等到当前的线程执行完按monitorexit指令之后,也就是被释放之后,处于等待队列的线程就可以开始竞争锁了。

wait和notify为什么要放在synchronized里面

wait方法的语义有两个,

  • 释放当前的对象锁、
  • 使得当前线程进入阻塞队列,

而这些操作都和监视器是相关的,所以wait必须要获得一个监视器锁。
notify也一样,它是唤醒一个线程,所以需要知道待唤醒的线程在哪里,就必须找到这个对象获取这个对象的锁然后去到这个对象的等待队列去唤醒一个线程。

以上是关于java并发 --wait与notify原理的主要内容,如果未能解决你的问题,请参考以下文章

Java并发总结-全景图

java中怎么实现高并发

Java 并发编程:核心理论

Java并发编程之美

[Java 并发] Java并发编程实践 思维导图 - 第一章 简单介绍

Java并发工具类Java并发容器