正文開始前先把lock接口的源碼擺出來(精簡後的,特意保留了部分註釋)
public interface Lock {
/**
* Acquires the lock.
*/
void lock();
/**
* Acquires the lock unless the current thread is
* {@linkplain Thread#interrupt interrupted}.
*/
void lockInterruptibly() throws InterruptedException;
/**
* Acquires the lock if it is free within the given waiting time and the
* current thread has not been {@linkplain Thread#interrupt interrupted}.
*/
boolean tryLock();
/**
* Acquires the lock if it is free within the given waiting time and the
* current thread has not been {@linkplain Thread#interrupt interrupted}.
*/
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
/**
* Releases the lock.
*/
void unlock();
/**
* Returns a new {@link Condition} instance that is bound to this
* {@code Lock} instance.
*/
Condition newCondition();
}
(1)使用lock()
和使用Synchronized關鍵字是一樣的效果,直接去獲取鎖。成功了就ok了,失敗了就阻塞等待了。不同的是lock鎖是可重入鎖,所以還是有不一樣的地方:
- 當鎖可用,並且當前線程沒有持有該鎖,直接獲取鎖並把count set爲1.
- 當鎖可用,並且當前線程已經持有該鎖,直接獲取鎖並把count增加1.
- 當鎖不可用,那麼當前線程被阻塞,休眠一直到該鎖可以獲取,然後把持有count設置爲1.
(2)使用tryLock()
- 當獲取鎖時,只有當該鎖資源沒有被其他線程持有纔可以獲取到,並且返回true,同時設置持有count爲1;
- 當獲取鎖時,當前線程已持有該鎖,那麼鎖可用時,返回true,同時設置持有count加1;
- 當獲取鎖時,如果其他線程持有該鎖,無可用鎖資源,直接返回false,這時候線程不用阻塞等待,可以先去做其他事情;
- 即使該鎖是公平鎖fairLock,使用tryLock()的方式獲取鎖也會是非公平的方式,只要獲取鎖時該鎖可用那麼就會直接獲取並返回true。這種直接插入的特性在一些特定場景是很有用的。但是如果就是想使用公平的方式的話,可以試一試tryLock(0, TimeUnit.SECONDS),幾乎跟公平鎖沒區別,只是會監測中斷事件。