线程间的通信
wait方法
Object方法,会释放锁。可做线程通信唤醒
sleep为线程方法不会释放锁
notify方法
通知其余线程
notify和notifyAll的区别:
1、notify只会随机选取一个处于等待池中的线程进入锁池去竞争获取锁的机会;
2、notifyAll会让所有处于等待池的线程全部进入锁池去竞争获取锁的机会;
注意notifyAll方法区别,具体由某个线程竞争到锁系java无法控制,由底层系统进行控制。
注意api 的使用
虚假唤醒问题
个人理解:当多个线程进行等待条件唤醒,但是唤醒时不满足唤醒执行条件即为虚假唤醒。
解决方案:
通过while循环,即便被唤醒,也会继续执行while条件判断,当满足条件后才可继续执行,进行避免虚假唤醒问题。
while(条件){
wait();
}
lock实现
主要api:lock,tryLock,unlock
通过实现condition进行条件加锁:
public static final Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
condition中通过await()进行新城等待(释放锁),通过signal进行唤醒。
condition中存在条件集合signal和signalAll可进行唤醒(需要再查一下资料,云里雾里)
lock手动加锁需要进行手动释放锁,否则出现线程堵塞finally执行解锁操作。
ReentrantLock 可重入锁
可重入锁概念: 一个线程可以多次获取同一个锁。
指定线程通信
一个对象的多个condition进行等待、唤醒操作 实现多线程指定通信
其中比较有意思的事通过阻塞队列进行通信。因为阻塞队列只有一个线程可以访问,可以通过队列的特性使其一个一个按顺序的执行。
LinkedBlockingQueue 本身是线程安全的,通过lock实现加锁