线程通讯(线程协作)
实现方式:
1.suspend【挂起】 resume【恢复执行】(被弃用)
问题:
a.不释放锁
b.对执行顺序要求严格
死锁情况A.同步代码中因为suspend不释放锁,resume也就获取不到锁,不能通知到suspend挂起的线程
死锁情况B.执行顺序不对容易死锁:多线程不确定性导致可能先执行了resume,而此时suspend由于在sleep没收到这个通知,就再也收不到通知去执行了)
2.wait notify/notifyAll:不会死锁,因为线程调用wait方法后会释放锁
问题:
对执行顺序要求严格
基于监视器实现:
这些方法必须只能有同一个对象锁的持有者线程调用(也就是写在代码块里,否则会抛出异常)
wait方法导致当前线程等待,加入该对象的等待集合中,并且释放当前持有的对象锁
notify/notifyAll 唤醒一个/所有正在等待这个对象锁的线程
注意:虽然wait()自动解锁,但是对顺序有要求,如果在notify()之后才调用wait()方法,则线程永远处于wait状态
3.park()/unpark()
问题:
不释放锁
多次unpakr之后,再调用park,线程会直接运行,不会叠加
注意:不是监视器原理实现。所以在同步代码synchronlized(){}中容易死锁
====================================================================
以上三种方法,都没有完美解决所有问题,所有推荐用后两种酌情使用
suspend/resume正常调用
死锁情况1:
死锁情况2;
wait()/notify()
park /unpark
正常调用
多线程通讯的一些小陷阱