ReentrantLock 鎖類
RenntrantLock.java 在擴展功能上比 synchronized 強很多,它具備嗅探鎖定、多路分支通知等相關功能。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class MyService{
private Lock lock = new ReentrantLock();
public void myMethod() {
lock.lock();
for (int i = 0; i < 3; i++) {
System.out.println("ThreadName=" + Thread.currentThread().getName() + ", 第" + (i+1) + "進入函數");
}
lock.unlock();
}
}
class ThreadA extends Thread{
private MyService myService;
public ThreadA(MyService myService){
super();
this.myService = myService;
}
@Override
public void run() {
super.run();
myService.myMethod();
}
}
public class test0 {
public static void main(String[] args) {
MyService myService = new MyService();
Thread a = new ThreadA(myService);
a.start();
Thread b = new ThreadA(myService);
b.start();
Thread c = new ThreadA(myService);
c.start();
}
}
ThreadName=Thread-0, 第1進入函數
ThreadName=Thread-0, 第2進入函數
ThreadName=Thread-0, 第3進入函數
ThreadName=Thread-2, 第1進入函數
ThreadName=Thread-2, 第2進入函數
ThreadName=Thread-2, 第3進入函數
ThreadName=Thread-1, 第1進入函數
ThreadName=Thread-1, 第2進入函數
ThreadName=Thread-1, 第3進入函數
Lock 接口的函數定義
- void lock(); : 獲得鎖。
- void unlock(); : 鬆開鎖。
- boolean tryLock();: 只有在調用時鎖是空閒的情況下才獲取鎖。
- boolean tryLock(long time, TimeUnit unit) throws InterruptedException; : 如果鎖在給定的等待時間內空閒並且當前線程未被 interrupt / interrupted標記,則獲取該鎖。
- Condition newCondition(); : 返回綁定到此 lock() 實例的新 Condition 實例。
- void lockInterruptibly() throws InterruptedException; : 獲取鎖,除非當前線程是被 interrupt / interrupted 標記過的。
Lock 接口的實現類
- ReadLock
- ReadLockView
- ReentrantLock
- WriteLock
- WriteLockView
Condition.java 監視器接口類
關鍵字 synchronized 與 wait() / notify() / notifyAll()方法相結合可以實現等待 / 通知模式, ReentrantLock 也可以實現同樣的通能,但是需要藉助於 Condition 對象。
Condition 監視器接口類的函數定義
- void await() throws InterruptedException;使當前線程等待,直到發出喚醒或觸發 interrupt / interrupted 標記。
- boolean await(long time, TimeUnit unit) throws InterruptedException;使當前線程等待,直到發出信號或被中斷,或者指定的等待時間結束。
- long awaitNanos(long nanosTimeout) throws InterruptedException;使當前線程等待,直到發出信號或被中斷,或者指定的等待時間結束。
- void awaitUninterruptibly(); : 使當前線程等待直到發出信號。
- boolean awaitUntil(Date deadline) throws InterruptedException; : 使當前線程等待,直到發出信號或被中斷,或者指定的截止時間過去。
- void signal(); : 喚醒一個等待線程。
- void signalAll(); : 喚醒全部等待線程。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class MyService{
private Lock lock = new ReentrantLock();
public Condition condition = lock.newCondition();
public void await() {
lock.lock();
System.out.println("await 時間爲:" + System.currentTimeMillis());
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void signal() {
try {
lock.lock();
System.out.println("Signal 時間爲:" + System.currentTimeMillis());
condition.signal();
} finally {
lock.unlock();
}
}
}
class ThreadA extends Thread{
private MyService myService;
public ThreadA(MyService myService) {
super();
this.myService = myService;
}
@Override
public void run() {
super.run();
myService.await();
}
}
public class test0 {
public static void main(String[] args) {
MyService myService = new MyService();
ThreadA a = new ThreadA(myService);
a.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
myService.signal();
}
}
await 時間爲:1592453263834
Signal 時間爲:1592453264833
所謂單個喚醒,即是在某類中設置多個 Condition ,並且只喚醒其中一個。