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 在執行