等待/通知机制
1.不适用等待/通知机制实现线程间的通信
主要一个线程通过不断地轮训来实现线程间的通信,轮询时间过小,浪费cpu资源,轮询时间过大,有可能取到不想要的结果
2.什么是等待/通知机制
服务员/厨师故事
3.等待/通知机制的实现
wait是线程停止,notify使挺值得线程继续运行
注:wait和notify运行都必须获得对象锁,否则会出异常IllegalMonitorStateException
notify执行后并不会立即释放锁,要等synchronized代码块/方法执行完之后才会释放
同时wait也不会立马获得锁。
wait()方法可以使调用该方法的线程释放共享资源的锁,然后从运行状态退出进入等待队列,直到再次被唤醒
notify()方法可以随机唤醒等待队列中等待同一共享资源的一个线程,并使该线程退出等待队列进入运行状态
notifyAll()方法可以使所有正在等待队列中等待同一共享资源的全部线程从等待状态退出,进入可运行状态,此时,优先级
高的的线程先执行,但也有可能随机执行,取决于jvm
a.新建一个线程后,调用它的start()方法,系统会给该线程分配cpu资源使其处于Runnable(可运行)状态,当其获得cpu资源
时,线程就进去Running(运行)状态
b.Runnable状态和Running状态可以互换,因为有可能一段时间后有其他优先级高的线程抢占cpu资源,线程就从Running状态
转为Runnable状态
线程进去Runnable状态5种情况
1.调用sleep()方法超过指定的休眠时间
2.线程调用的阻塞io已经返回,阻塞方法执行完毕
3.线程成功的获得试图同步的监视器
4.线程正在等待通知,其它线程发出通知
5.处于挂起状态的线程,调用resume恢复方法
c.Blocked是阻塞的意思
进入阻塞状态的5种情况
1.调用sleep主动放弃cpu资源
2.调用阻塞式io方法,在返回前该线程被阻塞
3.线程试图获得一个同步监视器,该监视器被其他线程持有
4.线程等待通知
5.调用了suspend()方法线程挂起,尽量不用,会导致死锁
d.run()执行后进入销毁阶段
每个锁对象都有两个队列,一个就绪队列,一个阻塞队列,就绪队列将要获得锁的线程,阻塞队列存储被阻塞的队列,一个
线程被唤醒后会进入就绪队列等待分配cpu资源,一个线程被wait之后会进去阻塞队列,等待下一次被唤醒。
4.方法wait()锁释放和notify()锁不释放
当wait方法执行后,锁会自动释放,但是notify方法执行后锁不会自动释放。
5.当interrupt方法遇到wait方法
当线程进入到wait方法时调用interrupt时,会抛出异常InterrupedException
总结: 1.执行完同步代码块就会释放对象的锁
2.在执行同步代码块的过程中出现异常,锁也会释放
3.执行同步代码块中的wait方法,线程会释放锁,从而进入等待队列,等待再一次被唤醒
6.只通知一个线程
notify(),任意一个
7.唤醒所有线程
notifyAll(),所有
8.方法wait(long)使用
带参数的wait(long)方法的功能是等待某一时间内是否有线程对锁进行唤醒,如果超过这个时间,会自动唤醒。
9.通知过早
如果通知过早会打乱程序正常的运行逻辑
10.等待wait的条件发生变化
等待wait的条件发生变化也容易造成程序逻辑的混乱
1.不适用等待/通知机制实现线程间的通信
主要一个线程通过不断地轮训来实现线程间的通信,轮询时间过小,浪费cpu资源,轮询时间过大,有可能取到不想要的结果
2.什么是等待/通知机制
服务员/厨师故事
3.等待/通知机制的实现
wait是线程停止,notify使挺值得线程继续运行
注:wait和notify运行都必须获得对象锁,否则会出异常IllegalMonitorStateException
notify执行后并不会立即释放锁,要等synchronized代码块/方法执行完之后才会释放
同时wait也不会立马获得锁。
wait()方法可以使调用该方法的线程释放共享资源的锁,然后从运行状态退出进入等待队列,直到再次被唤醒
notify()方法可以随机唤醒等待队列中等待同一共享资源的一个线程,并使该线程退出等待队列进入运行状态
notifyAll()方法可以使所有正在等待队列中等待同一共享资源的全部线程从等待状态退出,进入可运行状态,此时,优先级
高的的线程先执行,但也有可能随机执行,取决于jvm
a.新建一个线程后,调用它的start()方法,系统会给该线程分配cpu资源使其处于Runnable(可运行)状态,当其获得cpu资源
时,线程就进去Running(运行)状态
b.Runnable状态和Running状态可以互换,因为有可能一段时间后有其他优先级高的线程抢占cpu资源,线程就从Running状态
转为Runnable状态
线程进去Runnable状态5种情况
1.调用sleep()方法超过指定的休眠时间
2.线程调用的阻塞io已经返回,阻塞方法执行完毕
3.线程成功的获得试图同步的监视器
4.线程正在等待通知,其它线程发出通知
5.处于挂起状态的线程,调用resume恢复方法
c.Blocked是阻塞的意思
进入阻塞状态的5种情况
1.调用sleep主动放弃cpu资源
2.调用阻塞式io方法,在返回前该线程被阻塞
3.线程试图获得一个同步监视器,该监视器被其他线程持有
4.线程等待通知
5.调用了suspend()方法线程挂起,尽量不用,会导致死锁
d.run()执行后进入销毁阶段
每个锁对象都有两个队列,一个就绪队列,一个阻塞队列,就绪队列将要获得锁的线程,阻塞队列存储被阻塞的队列,一个
线程被唤醒后会进入就绪队列等待分配cpu资源,一个线程被wait之后会进去阻塞队列,等待下一次被唤醒。
4.方法wait()锁释放和notify()锁不释放
当wait方法执行后,锁会自动释放,但是notify方法执行后锁不会自动释放。
5.当interrupt方法遇到wait方法
当线程进入到wait方法时调用interrupt时,会抛出异常InterrupedException
总结: 1.执行完同步代码块就会释放对象的锁
2.在执行同步代码块的过程中出现异常,锁也会释放
3.执行同步代码块中的wait方法,线程会释放锁,从而进入等待队列,等待再一次被唤醒
6.只通知一个线程
notify(),任意一个
7.唤醒所有线程
notifyAll(),所有
8.方法wait(long)使用
带参数的wait(long)方法的功能是等待某一时间内是否有线程对锁进行唤醒,如果超过这个时间,会自动唤醒。
9.通知过早
如果通知过早会打乱程序正常的运行逻辑
10.等待wait的条件发生变化
等待wait的条件发生变化也容易造成程序逻辑的混乱