您學(xué)習(xí)了線程同步的基本概念以及使用synchronized關(guān)鍵字的各種機(jī)制。
Java提供了另一種基于鎖接口和實現(xiàn)它的類(如ReNANTTROLK)同步代碼塊的機(jī)制。在本教程中,我們將看到鎖接口的基本用法,以解決打印機(jī)隊列問題。Lock Interface
java.u是一種線程同步機(jī)制,與同步塊類似。然而,使用lock比同步塊更靈活、更復(fù)雜。由于Lock是一個接口,所以需要使用它的一個實現(xiàn)來在應(yīng)用程序中使用lock。ReentrantLock是鎖接口的一種實現(xiàn)。
下面是鎖接口的簡單用法。
Lock lock = new ReentrantLock();
lock.lock();
//critical section
lock.unlock();
上面首先創(chuàng)建一個鎖的實例。然后調(diào)用它的lock()方法。現(xiàn)在實例被鎖定。調(diào)用lock()的任何其他線程將被阻塞,直到鎖定該鎖的線程調(diào)用unlock()。
最后調(diào)用unlock(),lock現(xiàn)在被解鎖,以便其他線程可以鎖定它。
Lock Interface和synchronized關(guān)鍵字之間的區(qū)別
Lock和synchronized塊之間的主要區(qū)別是:
1)嘗試訪問同步塊時發(fā)生超時是不可能的。 使用Lock.tryLock(長超時,TimeUnit timeUnit),這是可能的。
2)synchronized必須完全包含在單個方法中。 Lock可以在單獨的方法中調(diào)用lock()和unlock()。
使用lock模擬打印機(jī)隊列
在本例中,程序?qū)⒛M打印機(jī)的行為。您可以在不同的時間間隔或同時向打印機(jī)提交多個打印作業(yè)。打印機(jī)將從打印機(jī)隊列中獲取一個作業(yè)并打印它。其余的工作將在那里等待。一旦打印機(jī)完成手頭的打印作業(yè),它將從隊列中選擇另一個作業(yè)并開始打印。然后再循環(huán)。
Prin
此類表示可以提交給打印機(jī)的打印工作。這個類實現(xiàn)了可運行的接口,這樣打印機(jī)可以在輪到它時執(zhí)行它。
class PrintingJob implements Runnable
{
private PrinterQueue printerQueue;
public PrintingJob(PrinterQueue printerQueue)
{
= printerQueue;
}
@Override
public void run()
{
Sy("%s: Going to print a document\n", ().getName());
(new Object());
}
}
Prin
此類表示打印機(jī)隊列/打印機(jī)。 當(dāng)前打印作業(yè)完成后,打印機(jī)將保持鎖定以啟動新的打印作業(yè)。
class PrinterQueue
{
private final Lock queueLock = new ReentrantLock();
public void printJob(Object document)
{
queueLock.lock();
try
{
Long duration = (long) () * 10000);
Sy().getName() + ": PrintQueue: Printing a Job during " + (duration / 1000) + " seconds :: Time - " + new Date());
T(duration);
} catch (InterruptedException e)
{
e.printStackTrace();
} finally
{
Sy("%s: The document has been printed\n", T().getName());
queueLock.unlock();
}
}
}
讓我們測試一下打印機(jī)程序:
public class LockExample
{
public static void main(String[] args)
{
PrinterQueue printerQueue = new PrinterQueue();
Thread thread[] = new Thread[10];
for (int i = 0; i < 10; i++)
{
thread[i] = new Thread(new PrintingJob(printerQueue), "Thread " + i);
}
for (int i = 0; i < 10; i++)
{
thread[i].start();
}
}
}
最終輸出:
Thread 0: Going to print a document
Thread 9: Going to print a document
Thread 8: Going to print a document
Thread 7: Going to print a document
Thread 5: Going to print a document
Thread 6: Going to print a document
Thread 4: Going to print a document
Thread 3: Going to print a document
Thread 2: Going to print a document
Thread 1: Going to print a document
Thread 0: PrintQueue: Printing a Job during 8 seconds :: Time - Tue Jan 06 15:19:02 IST 2015
Thread 0: The document has been printed
Thread 9: PrintQueue: Printing a Job during 1 seconds :: Time - Tue Jan 06 15:19:11 IST 2015
Thread 9: The document has been printed
Thread 8: PrintQueue: Printing a Job during 8 seconds :: Time - Tue Jan 06 15:19:12 IST 2015
Thread 8: The document has been printed
Thread 7: PrintQueue: Printing a Job during 9 seconds :: Time - Tue Jan 06 15:19:21 IST 2015
Thread 7: The document has been printed
Thread 5: PrintQueue: Printing a Job during 7 seconds :: Time - Tue Jan 06 15:19:31 IST 2015
Thread 5: The document has been printed
Thread 6: PrintQueue: Printing a Job during 5 seconds :: Time - Tue Jan 06 15:19:39 IST 2015
Thread 6: The document has been printed
Thread 4: PrintQueue: Printing a Job during 2 seconds :: Time - Tue Jan 06 15:19:44 IST 2015
Thread 4: The document has been printed
Thread 3: PrintQueue: Printing a Job during 2 seconds :: Time - Tue Jan 06 15:19:46 IST 2015
Thread 3: The document has been printed
Thread 2: PrintQueue: Printing a Job during 5 seconds :: Time - Tue Jan 06 15:19:49 IST 2015
Thread 2: The document has been printed
Thread 1: PrintQueue: Printing a Job during 5 seconds :: Time - Tue Jan 06 15:19:54 IST 2015
Thread 1: The document has been printed
該示例的關(guān)鍵點是PrinterQueue類的printJob()方法。 當(dāng)我們想要使用lock實現(xiàn)一個critical section并保證只有一個執(zhí)行線程運行一個代碼塊時,我們必須創(chuàng)建一個ReentrantLock對象。 在critical section的開頭,我們必須使用lock()方法來控制鎖。
在critical section的末尾,我們必須使用unlock()方法釋放對鎖的控制,并允許其他線程運行這個critical section。如果不在critical section的末尾調(diào)用unlock()方法,則等待該塊的其他線程將永遠(yuǎn)等待,從而導(dǎo)致死鎖情況。如果在critical section使用try catch塊,請不要忘記將包含unlock()方法的語句放在finally部分中。
如果你喜歡請收藏!
1.《工作十年的java工程師告訴你如何使用lock》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識,僅代表作者本人觀點,與本網(wǎng)站無關(guān),侵刪請聯(lián)系頁腳下方聯(lián)系方式。
2.《工作十年的java工程師告訴你如何使用lock》僅供讀者參考,本網(wǎng)站未對該內(nèi)容進(jìn)行證實,對其原創(chuàng)性、真實性、完整性、及時性不作任何保證。
3.文章轉(zhuǎn)載時請保留本站內(nèi)容來源地址,http://f99ss.com/why/2998323.html