Java 高并发程序设计学习笔记--wait 和notify
2018-01-25 17:13
387 查看
等待(wait) 和 通知(notify)
说明: 文本是学习了《Java 高并发程序设计》中的等待和通知内容的学习笔记,结合实例总结了一些小结论。wait () 方法顾名思义就是线程处于等待状态,当程序执行遇到synchronize同步块时,线程会进入BLOCKED阻塞状态,此时线程暂时停止执行知道获取到请求锁。当调用wait方法时,线程就会进入WAITING状态,知道等待到一个notify方法,线程就会重新执行。提到wait,join方法也是等待方法,两者的区别是wait等到notify就会继续执行,而join会等到目标线程终止。
wait和notify的使用,这两个方法不是Thread类中的方法,而是输入的Object对象的方法,如果线程A调用了object.wait,那么线程A会处于等待状态,直到其他线程调用了object.notify,A才会继续执行。
下面是一个简单的小例子:
private static Object object = new Object(); public static class T1 extends Thread { @Override public void run() { synchronized (object) { try { System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getId() + " T1 start "); System.out.println("T1 wait 1"); object.wait(); } catch (InterruptedException e) { System.out.println("T1 InterruptedException"); } System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getId() +" T1 end!"); } } } public static class T2 extends Thread { @Override public void run() { synchronized (object) { try { System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getId() + " T2 start "); System.out.println(" T2 notify"); object.notify(); Thread.sleep(3000); } catch (InterruptedException e) { System.out.println("T2 InterruptedException"); } System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getId() +" T2 end!"); } } } public static void main(String[] args) throws Exception{ new T1().start(); new T2().start(); }
执行的结果是:
根据控制台输出的结果可以看出,当T2调用了object.notify()后,T1并没有立即执行,而是等待T2执行完之后,T1才获取到锁,重新继续执行。
如果在T1中调用两次wait,T2中notify两次,T1会end么?
public static class T1 extends Thread { @Override public void run() { synchronized (object) { try { System.out.println(System.currentTimeMillis() + " : threadId:" + Thread.currentThread().getId() + " T1 start "); System.out.println("T1 第一次wait 1"); object.wait(); System.out.println(System.currentTimeMillis() + " : T1 第二次 wait 2"); object.wait(); } catch (InterruptedException e) { System.out.println("T1 InterruptedException"); } System.out.println(System.currentTimeMillis() + " : threadId:" + Thread.currentThread().getId() +" T1 end!"); } } } public static class T2 extends Thread { @Override public void run() { synchronized (object) { try { System.out.println(System.currentTimeMillis() + " : threadId:" + Thread.currentThread().getId() + " T2 start "); System.out.println("T2 第一次notify"); object.notify(); Thread.sleep(3000); System.out.println("T2 第二次notify"); object.notify(); Thread.sleep(2000); } catch (InterruptedException e) { System.out.println("T2 InterruptedException"); } System.out.println(System.currentTimeMillis() + " : threadId:" + Thread.currentThread().getId() +" T2 end!"); } } }
此时的结果如下:
如图所示,T1第一次wait是在T2结束之后被通知的,第二次wait一直处于等待状态。
如何将T1执行结束呢?
public static class T2 extends Thread { @Override public void run() { synchronized (object) { try { System.out.println(System.currentTimeMillis() + " : threadId:" + Thread.currentThread().getId() + " T2 start "); System.out.println("T2 第一次notify"); object.notify(); Thread.sleep(3000); } catch (InterruptedException e) { System.out.println("T2 InterruptedException"); } System.out.println(System.currentTimeMillis() + " : threadId:" + Thread.currentThread().getId() +" T2 end!"); } } } public static void main(String[] args) throws Exception{ new T1().start(); new T2().start(); new T2().start(); // 或者第二中方式 new T1().start(); new T2().start(); Thread.sleep(5000); synchronized (object) { System.out.println(System.currentTimeMillis() + " object.notify()"); object.notify(); } }
结果如下:
第二中方式的结果如下:
如图,当新创建一个T2时,T1可以继续执行知道End。
当T1调用object.wait 时,object的锁被释放,T2调用object.notify时获取到object的锁,当T2执行完之后释放了object锁,此时T1获取到了object的锁,继续程序。第二个例子中,将T1调用了两次wait,T2调用了两次notify,但是T1没有继续执行,而是停在了第二次wait,由于T2执行结束,所以T1第一次等待被唤醒,第二次等待由于T2已经完成所以第二次的wait获取不到notify的唤醒,一直处于等待状态。
第三个例子中,重新new了一个T2,此时的T2和第一次New的T2是两个完全不用的线程。从结果也可以看出,当id为13的线程结束是T1才结束,也就是说T1的第二个wait是id为13的线程唤醒的。
相关文章推荐
- java高并发程序设计学习笔记八BIO、NIO和AIO
- java并发学习笔记(一):wait() notifyAll() 生产者 消费者
- Java核心知识点学习----多线程并发之线程间的通信,notify,wait
- Java 多线程学习笔记 线程通讯 wait notify notifyAll的理解
- java高并发程序设计学习笔记四无锁
- java高并发程序设计学习笔记三内存模型线程安全
- 并发学习笔记(三):join与wait/notify
- java高并发程序设计学习笔记九锁的优化和注意事项
- Java学习笔记81. 线程间的通信 —— wait( ),notify( ),和 notifyAll( )
- Java并发学习 & Executor学习 & 异常逃逸 & 同步互斥Best Practice & wait/notify, conditon#await/signal
- java高并发程序设计学习笔记一前言
- Java 多线程学习笔记:wait、notify、notifyAll的阻塞和恢复
- java高并发程序设计学习笔记五六JDK并发包
- Java并发学习笔记(13)线程之间的协作(Object.wait(),notifu(),notifyAll() Thread.join())
- java高并发程序设计学习笔记二多线程基础
- java 数据库程序设计 学习笔记
- java并发包学习笔记(一)
- Java 并发编程学习笔记 理解CLH队列锁算法
- Java 并发编程实战学习笔记——寻找可强化的并行性
- java学习笔记之线程并发库