|
|
51CTO旗下网站
|
|
移动端

1.7.3 wait/notify/notifyAll

《Java多线程与Socket:实战微服务框架》第1章多线程基础,本书尽量采用简要和通俗易懂的方式来介绍多线程知识。本节为大家介绍wait/notify/notifyAll。

作者:庞永华来源:电子工业出版社|2019-03-26 15:56

【大咖·来了 第7期】10月24日晚8点观看《智能导购对话机器人实践》

1.7.3 wait/notify/notifyAll

如果线程1在获取对象a的锁后(在某个synchronized作用域内),需要等待线程2的执行结果,那么最理想的办法就是由线程2来“通知”线程1继续执行。类似这种在线程间传递信息的动作,被称为线程间通信。

Object类的wait()/notify()/notifyAll()方法就是为此而设计的,其是线程间通信的重要手段之一。由于这3个方法都是基于synchronized关键字所提供的对象锁来实现的,因此,它们只能在由synchronized关键字修饰的同步方法或者同步块里面使用。

调用a.wait() 方法会使得当前线程(线程1)放弃它持有的对象a的锁,进入阻塞状态。直到别的线程(线程2)抢到对象a的锁,并调用a.notify() 或a.notifyAll()后,线程1才可能被唤醒,重新回到“就绪”状态。

注意,如果有10个线程先后抢到了对象a的锁,并都调用了a.wait() 方法,那么当某个线程抢到对象a的锁,并调用a.notify()时,将唤醒这10个线程中的一个;调用a.notifyAll() 则会将这10个线程全部唤醒,让它们都回到就绪状态,但最终只有一个线程能通过竞争获取到锁而得以执行。

此外,notify()/notifyAll()只是唤醒某个阻塞状态的线程,而不会释放锁。所以在编程中,尽量在使用了notify()/notifyAll()后立即退出临界区,以便被唤醒的线程可以尽快执行。

请运行并思考下面这个例子:

  1. public class C1_7_3 implements Runnable {  
  2. private static final Logger log = LoggerFactory.getLogger(C1_7_3.class);  
  3. private static final byte[] flag = new byte[0];  
  4. public void run() {  
  5. synchronized (flag) {  
  6. try {  
  7. log.info("Before flag.wait()");  
  8. flag.wait();  
  9. log.info("After flag.wait()");  
  10. Thread.sleep(1000L); // 换成flag.wait(1000L)试试  
  11. log.info("After Thread.sleep()");  
  12. } catch (InterruptedException e) {  
  13. e.printStackTrace();  
  14. }  
  15. }  
  16. }  
  17. public static void main(String[] args) throws InterruptedException {  
  18. ExecutorService es = Executors.newCachedThreadPool();  
  19. es.execute(new C1_7_3());  
  20. es.execute(new C1_7_3());  
  21. es.execute(new Runnable() {  
  22. @Override  
  23. public void run() {  
  24. try {  
  25. Thread.sleep(1000L);  
  26. } catch (InterruptedException e) {  
  27. e.printStackTrace();  
  28. }  
  29. synchronized (flag) {  
  30. log.info("flag.notifyAll()");  
  31. flag.notifyAll(); // 换成notify试试  
  32. }  
  33. }  
  34. });  
  35. es.shutdown();  


喜欢的朋友可以加入官方的读书群

51CTO读书频道二维码


51CTO读书会第9群:808517103

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

Jenkins Pipeline可持续化集成

Jenkins Pipeline可持续化集成

优化运维流水线
共3章 | youerning

198人订阅学习

笑熬浆糊之职场那些事

笑熬浆糊之职场那些事

IT人的职场心法
共22章 | Bear_Boss

79人订阅学习

Redis运维秘籍

Redis运维秘籍

运维标配技术
共15章 | one叶孤舟

199人订阅学习

读 书 +更多

ASP.NET 2.0数据库开发实例精粹

本书分为8章,首先介绍ASP.NET的开发技巧和重点技术,尤其针对初学者如何快速入门并掌握ASP.NET编程做了深入浅出的介绍;然后重点介绍ASP.N...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO播客