Lock的特性:
- Lock不是Java语言内置的;
- synchronized是在JVM层面上实现的,如果代码执行出现异常,JVM会自动释放锁,但是Lock不行,要保证锁一定会被释放,就必须将unLock放到finally{}中(手动释放);
- 在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReetarntLock,但是在很激烈的情况下,synchronized的性能会下降几十倍;
- ReentrantLock增加了锁
void lock(); // 无条件的锁;
void lockInterruptibly throws InterruptedException;//可中断的锁;
使用ReentrantLock如果获取了锁立即返回,如果没有获取锁,当前线程处于休眠状态,直到获得锁或者当前线程可以被别的线程中断去做其他的事情;但是如果是synchronized的话,如果没有获取到锁,则会一直等待下去;
boolean tryLock();//如果获取了锁立即返回true,如果别的线程正持有,立即返回false,不会等待;
boolean tryLock(long timeout,TimeUnit unit);//如果获取了锁立即返回true,如果别的线程正持有锁,会等待参数给的时间,在等待的过程中,如果获取锁,则返回true,如果等待超时,返回false;
Condition的特性:
- Condition中的await()方法相当于Object的wait()方法
- Condition中的signal()方法相当于Object的notify()方法
- Condition中的signalAll()相当于Object的notifyAll()方法。
- 不同的是,Object中的这些方法是和同步锁捆绑使用的,而Condition是需要与互斥锁/共享锁捆绑使用的。
- Condition能够更加精细的控制多线程的休眠与唤醒。对于同一个锁,我们可以创建多个Condition,在不同的情况下使用不同的Condition。
Condition的案例
/**
* @Author feizhou
* @Description 测试让多线程按顺序执行,这里是 线程1,线程2,线程3
* @Date 上午 12:40 2019/8/30 0030
* @Param
* @return
**/
public class ConditionTest {
private int conditionValue = 1;
Lock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();
/**
* @param args
*/
public static void main(String[] args) throws InterruptedException {
ConditionTest conditionTest=new ConditionTest();
//线程3
new Thread(
new Runnable() {
@Override
public void run() {
conditionTest.test3();
}
}
).start();
Thread.sleep(2000);
//线程2
new Thread(
new Runnable() {
@Override
public void run() {
conditionTest.test2();
}
}
).start();
Thread.sleep(2000);
//线程1
conditionTest.test1();
}
public void test1(){
lock.lock();
try{
while(conditionValue != 1){
System.out.println("test1 在等待");
condition1.await();
}
System.out.println("test1 在执行");
conditionValue = 2;
condition2.signal();
} catch (Exception e) {
e.printStackTrace();
} finally{
lock.unlock();
}
}
public void test2(){
lock.lock();
try{
while(conditionValue != 2){
System.out.println("test2 在等待");
condition2.await();
}
System.out.println("test2 在执行");
conditionValue = 3;
condition3.signal();
} catch (Exception e) {
e.printStackTrace();
} finally{
lock.unlock();
}
}
public void test3(){
lock.lock();
try{
while(conditionValue != 3){
System.out.println("test3 在等待");
condition3.await();
}
System.out.println("test3 在执行");
conditionValue = 3;
condition3.signal();
} catch (Exception e) {
e.printStackTrace();
}finally{
lock.unlock();
}
}
}
结果
test3 在等待
test2 在等待
test1 在执行
test2 在执行
test3 在执行