【Java并发编程】控制块(保护块)
来源:互联网 发布:linux 剪切文件夹 编辑:程序博客网 时间:2024/04/20 03:25
Guard Block
Guard Block,是一种常见的多个线程通信的代码形式。例如下面的代码,就可以称作Guard Block。这里有一个空循环,joy初始值初始值为false,程序将进入while循环中,直到joy的值变为false为止。这里的joy就是Guard Block中Guard的含义,像是一个守卫一样。
public void guardedJoy() { // Simple loop guard. Wastes // processor time. Don't do this! while(!joy) {} System.out.println("Joy has been achieved!");}
但是我们并不应该像上面的方式一样书写代码,以为while循环会一直执行,这将消耗CPU的能力。因此,我们下面要说面一种Java语言的多线程间的通信机制。不知道大家还是否记得,我们在前面介绍interrupt的时候说过,interrupt本身也是一种通信机制,是让设计成耗时任务可以抛出InterruptException的方法中断,停止执行,代码走异常处理。今天这要说的这两个(或者说三个)方法,是专门设计成线程间通信的。
wait
首先说wait方法是Object类的方法,并且声明成final的,不能被子类重写。因此我们创建一个类,并在其中调用wait方法时,实际上调用的就是Object中的wait方法。wait方法是可以让线程挂起,暂停执行的。我们看一下用wait方法更改上面的代码。
public synchronized void guardedJoy() { // This guard only loops once for each special event, which may not // be the event we're waiting for. while(!joy) { try { wait(); } catch (InterruptedException e) {} } System.out.println("Joy and efficiency have been achieved!");}
与其他耗时方法一样,wait方法也是抛出了InterruptException。需要我们捕获处理。wait方法会使得线程一直阻塞在那里,知道某种事件发生才会唤醒(后面马上会提到)。
除此之外,新方法变成了synchronized修饰的同步方法。这是由于wait方法执行之前,需要首先获取对象的内在锁。否则将会抛出一个错误,而通过加锁的方式,我们获取了这个内在锁。当wait执行了之后,线程挂起。这个时候,线程一直停在wait方法处,同时,wait方法释放了刚刚获取的内在锁。
notify,notifyAll
前面说到,wait方法挂起了当前线程后释放了内在锁。当另一个线程想要唤醒那个线程的时候,调用notify或者notifyAll,也需要获得同一把锁。
public synchronized notifyJoy() { joy = true; notifyAll();}
当notify或者notifyAll所在方法执行完毕后,会释放该锁,而此时wait方法再次获得该锁,进而暂停的线程可以继续执行。
notify和notifyAll的区别在于,由于wait方法挂起了线程后就释放掉了内在锁,所以,多个线程可以多次调用guardedJoy方法,也就是多个线程可以同时挂起,这是,如果调用notifyAll,那么所有挂起的线程都会醒来,而notify只能唤醒一个,并且不能确定是哪一个被唤醒。
- 【Java并发编程】控制块(保护块)
- Java并发编程(五)保护块
- java并发(五、保护块)
- java并发编程-构建块
- java并发编程-构建块
- java并发编程实践学习(4)构建块
- (六)java并发编程--synchronized同步块
- 【并发编程】Java同步块synchronized
- Java并发编程(Java Concurrency)(12)- Java 同步代码块(Java Synchronized Blocks)
- 保护块(Guarded Blocks)
- java并发实践------构建块(building blocks)
- Java并发系列-10、Java同步块
- java并发-java同步块(8)
- Guarded Blocks 保护块
- 进程控制块(PCB)
- java代码块(初始化块)
- java并发编程实践学习(5)构建块为计算结果建立高效,可伸缩的高速缓存
- Java(代码块)
- swift_035(Swift之第三方库Kingfisher篇)
- 数据清洗-- 使用Python脚本处理excel单元格换行符
- 声明
- eclipse 常用的快捷键
- Hbuild中字体设置
- 【Java并发编程】控制块(保护块)
- 解决多表关联删除的问题,深度为3
- javaScript中DOM和BOM--基础二
- 2017 Multi-University Training Contest
- java中的四种引用,强、软、弱、虚
- SpringBoot支持JSP访问,启动报错java.lang.NoClassDefFoundError: javax/servlet/ServletContext
- 数人云|从0到1,打造DevOps易用工具链(精挑细选27种)
- 图片base64加密为字符串
- MyBatis 二级缓存cache官方解释