没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
在多线程的情况下,由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题。
Java 语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问。
wait 与 notify 是 java 同步机制中重要的组成部分。结合与 synchronized 关键字使用,可以建立很多优秀的同步模型。
synchronized(this){ }等价于 publicsynchronized void method(){.....}
同步分为类级别和对象级别,分别对应着类锁和对象锁。类锁是每个类只有一个,如果 static 的方法被 synchronized 关键字
修饰,则在这个方法被执行前必须获得类锁;对象锁类同。
首先,调用一个 Object 的 wait 与 notify/notifyAll 的时候,必须保证调用代码对该 Object 是同步的,也就是说必须在作用等同
于 synchronized(obj){......}的内部才能够去调用 obj 的 wait 与 notify/notifyAll 三个方法,否则就会报错:
java.lang.IllegalMonitorStateException:current thread not owner
在调用 wait 的时候,线程自动释放其占有的对象锁,同时不会去申请对象锁。当线程被唤醒的时候,它才再次获得了去获得
对象锁的权利。
所以,notify 与 notifyAll 没有太多的区别,只是 notify 仅唤醒一个线程并允许它去获得锁,notifyAll 是唤醒所有等待这个对象
的线程并允许它们去获得对象锁,只要是在 synchronied 块中的代码,没有对象锁是寸步难行的。其实唤醒一个线程就是重新
允许这个线程去获得对象锁并向下运行。
notifyAll,虽然是对每个 wait 的对象都调用一次 notify,但是这个还是有顺序的,每个对象都保存这一个等待对象链,调用的
顺序就是这个链的顺序。其实启动等待对象链中各个线程的也是一个线程,在具体应用的时候,需要注意一下。
wait(),notify(),notifyAll()不属于 Thread 类,而是属于 Object 基础类,也就是说每个对像都有 wait(),notify(),notifyAll()的功能。因
为都个对像都有锁,锁是每个对像的基础,当然操作锁的方法也是最基础了。
wait():
等待对象的同步锁,需要获得该对象的同步锁才可以调用这个方法,否则编译可以通过,但运行时会收到一个异常:
IllegalMonitorStateException。
调用任意对象的 wait() 方法导致该线程阻塞,该线程不可继续执行,并且该对象上的锁被释放。
notify():
唤醒在等待该对象同步锁的线程(只唤醒一个,如果有多个在等待),注意的是在调用此方法的时候,并不能确切的唤醒某一个等待
状态的线程,而是由 JVM 确定唤醒哪个线程,而且不是按优先级。
调用任意对象的 notify()方法则导致因调用该对象的 wait()方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才
真正可执行)。
notifyAll():
唤醒所有等待的线程,注意唤醒的是 notify 之前 wait 的线程,对于 notify 之后的 wait 线程是没有效果的。
通常,多线程之间需要协调工作:如果条件不满足,则等待;当条件满足时,等待该条件的线程将被唤醒。在 Java 中,这个
机制的实现依赖于 wait/notify。等待机制与锁机制是密切关联的。
例如:
synchronized(obj) {
while(!condition) {
obj.wait();
}
obj.doSomething();
}
当线程 A 获得了 obj 锁后,发现条件 condition 不满足,无法继续下一处理,于是线程 A 就 wait()。
在另一线程 B 中,如果 B 更改了某些条件,使得线程 A 的 condition 条件满足了,就可以唤醒线程 A :
synchronized(obj) {
资源评论
u010344065
- 粉丝: 0
- 资源: 2
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功