您學(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