为什么需要锁?
很多时候,代码的执行并不是元操作。即代码是被拆分成很多条语句执行的,如果在其中某一条语句执行时突然有其他线程运行,很可能数据会出现问题。
这时候引入锁来保证在一个线程对某一部分代码进行操作时其他线程不能操作该部分代码。
ReentrantLock(可重入锁)
线程可以重复的获得已经持有的锁,锁保持一个持有计数来跟踪嵌套,当所有嵌套均结束,锁才被真正释放。
用ReentrantLock保护代码块的基本结构:
private Lock lock = new ReentrantLock();
lock.lock();
try{
//code
}
finally{
lock.unlock();
}
这一结构确保任何时刻只有一个线程进入临界区,一旦一个线程封锁了锁对象,其他任何线程都无法通过lock区域。
条件对象
一个线程等待另一个线程的操作。
初始化:
private Condition condition;
condition=lock.newCondition;
使用(进入等待状态):
condition.await();
解除:
condition.signalAll(); //解除全部
condition.signal(); //随机解除一个
使用第一个方法会激活因为这一条件而等待的所有线程。
通常,以如下形式调用await:
while(!(可以运行)){
condition.await();
}
synchronized:
java中的每一个对象都有一个内部锁,如果一个方法使用synchronized声明,那么对象的锁将保护整个方法。
wait(); //添加线程到等待集中
notifyAll(); //解除等待线程的阻塞状态
例子:
public synchronized void xxxx(){
while(!()){
wait();
}
//...
notifyAll();
}