- Java 併發教程
- 併發 - 首頁
- 併發 - 概述
- 併發 - 環境設定
- 併發 - 主要操作
- 執行緒間通訊
- 併發 - 同步
- 併發 - 死鎖
- 實用類示例
- 併發 - ThreadLocal
- 併發 - ThreadLocalRandom
- Lock 示例
- 併發 - Lock
- 併發 - ReadWriteLock
- 併發 - Condition
- 原子變數示例
- 併發 - AtomicInteger
- 併發 - AtomicLong
- 併發 - AtomicBoolean
- 併發 - AtomicReference
- 併發 - AtomicIntegerArray
- 併發 - AtomicLongArray
- 併發 - AtomicReferenceArray
- Executor 示例
- 併發 - Executor
- 併發 - ExecutorService
- ScheduledExecutorService
- 執行緒池示例
- 併發 - newFixedThreadPool
- 併發 - newCachedThreadPool
- newScheduledThreadPool
- newSingleThreadExecutor
- 併發 - ThreadPoolExecutor
- ScheduledThreadPoolExecutor
- 高階示例
- 併發 - Futures 和 Callables
- 併發 - Fork-Join 框架
- 併發集合
- 併發 - BlockingQueue
- 併發 - ConcurrentMap
- ConcurrentNavigableMap
- 併發有用資源
- 併發 - 快速指南
- 併發 - 有用資源
- 併發 - 討論
Java 併發 - Lock 介面
java.util.concurrent.locks.Lock 介面用作執行緒同步機制,類似於 synchronized 塊。新的鎖定機制比 synchronized 塊更靈活,並提供了更多選項。Lock 和 synchronized 塊之間的主要區別如下:
順序保證 - synchronized 塊不提供任何關於等待執行緒將獲得訪問許可權的順序的保證。Lock 介面處理此問題。
無超時 - 如果未授予鎖,則 synchronized 塊沒有超時選項。Lock 介面提供了此選項。
單個方法 - synchronized 塊必須完全包含在單個方法中,而 Lock 介面的 lock() 和 unlock() 方法可以在不同的方法中呼叫。
Lock 方法
以下是 Lock 類中可用的一些重要方法。
| 序號 | 方法和描述 |
|---|---|
| 1 | public void lock() 獲取鎖。 |
| 2 | public void lockInterruptibly() 除非當前執行緒被中斷,否則獲取鎖。 |
| 3 | public Condition newCondition() 返回一個新的 Condition 例項,該例項繫結到此 Lock 例項。 |
| 4 | public boolean tryLock() 僅當在呼叫時鎖為空閒時才獲取鎖。 |
| 5 | public boolean tryLock(long time, TimeUnit unit) 如果在給定的等待時間內鎖為空閒並且當前執行緒未被中斷,則獲取鎖。 |
| 6 | public void unlock() 釋放鎖。 |
示例
以下 TestThread 程式演示了 Lock 介面的一些方法。在這裡,我們使用 lock() 獲取鎖,並使用 unlock() 釋放鎖。
即時演示import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class PrintDemo {
private final Lock queueLock = new ReentrantLock();
public void print() {
queueLock.lock();
try {
Long duration = (long) (Math.random() * 10000);
System.out.println(Thread.currentThread().getName()
+ " Time Taken " + (duration / 1000) + " seconds.");
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.printf(
"%s printed the document successfully.\n", Thread.currentThread().getName());
queueLock.unlock();
}
}
}
class ThreadDemo extends Thread {
PrintDemo printDemo;
ThreadDemo(String name, PrintDemo printDemo) {
super(name);
this.printDemo = printDemo;
}
@Override
public void run() {
System.out.printf(
"%s starts printing a document\n", Thread.currentThread().getName());
printDemo.print();
}
}
public class TestThread {
public static void main(String args[]) {
PrintDemo PD = new PrintDemo();
ThreadDemo t1 = new ThreadDemo("Thread - 1 ", PD);
ThreadDemo t2 = new ThreadDemo("Thread - 2 ", PD);
ThreadDemo t3 = new ThreadDemo("Thread - 3 ", PD);
ThreadDemo t4 = new ThreadDemo("Thread - 4 ", PD);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
這將產生以下結果。
輸出
Thread - 1 starts printing a document Thread - 4 starts printing a document Thread - 3 starts printing a document Thread - 2 starts printing a document Thread - 1 Time Taken 4 seconds. Thread - 1 printed the document successfully. Thread - 4 Time Taken 3 seconds. Thread - 4 printed the document successfully. Thread - 3 Time Taken 5 seconds. Thread - 3 printed the document successfully. Thread - 2 Time Taken 4 seconds. Thread - 2 printed the document successfully.
我們在這裡使用 ReentrantLock 類作為 Lock 介面的實現。ReentrantLock 類允許執行緒鎖定一個方法,即使它已經擁有另一個方法的鎖。