
- 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 類允許執行緒鎖定一個方法,即使它已經擁有另一個方法的鎖。