JAVA線程的實(shí)現(xiàn)--Thread類與Runnable接口
要記住的一件重要的事情是main() 函數(shù)也是一個(gè)線程,并可用來(lái)做有用的工作。程序員只有在需要多個(gè)線程時(shí)才需要?jiǎng)?chuàng)建新的線程。
Thread 類
Thread 類是一個(gè)具體的類,而非抽象類.該類封裝了線程的行為。要?jiǎng)?chuàng)建一個(gè)線程,必須創(chuàng)建一個(gè)從 Thread 類繼承的新類。程序員必須覆蓋 Thread 的 run() 函數(shù)來(lái)完成有用的工作。用戶并不直接調(diào)用此函數(shù);而是必須調(diào)用 Thread 的 start() 函數(shù),該函數(shù)再調(diào)用 run()。下面的代碼說(shuō)明了它的用法:
創(chuàng)建兩個(gè)新線程:






























Runnable 接口
此接口只有一個(gè)函數(shù),run(),此函數(shù)必須由實(shí)現(xiàn)了此接口的類實(shí)現(xiàn)。但是,就運(yùn)行這個(gè)類而論,其語(yǔ)義與前一個(gè)示例稍有不同。我們可以用 runnable 接口改寫(xiě)前一個(gè)示例。
創(chuàng)建兩個(gè)新線程而不強(qiáng)加類層次:




























練習(xí):































































synchronized(同步的) 關(guān)鍵字
到目前為止,我們看到的示例都只是以非常簡(jiǎn)單的方式來(lái)利用線程。只有最小的數(shù)據(jù)流,而且不會(huì)出現(xiàn)兩個(gè)線程訪問(wèn)同一個(gè)對(duì)象的情況。但是,在大多數(shù)有用的程序中,線程之間通常有信息流。試考慮一個(gè)金融應(yīng)用程序,它有一個(gè) Account 對(duì)象,如下例中所示:
一個(gè)銀行中的多項(xiàng)活動(dòng):




















在此代碼樣例中潛伏著一個(gè)錯(cuò)誤。如果此類用于單線程應(yīng)用程序,不會(huì)有任何問(wèn)題。但是,在多線程應(yīng)用程序的情況中,不同的線程就有可能同時(shí)訪問(wèn)同一個(gè) Account 對(duì)象,比如說(shuō)一個(gè)聯(lián)合帳戶的所有者在不同的 ATM 上同時(shí)進(jìn)行訪問(wèn)。在這種情況下,存入和支出就可能以這樣的方式發(fā)生:一個(gè)事務(wù)被另一個(gè)事務(wù)覆蓋。這種情況將是災(zāi)難性的。但是,Java 編程語(yǔ)言提供了一種簡(jiǎn)單的機(jī)制來(lái)防止發(fā)生這種覆蓋。每個(gè)對(duì)象在運(yùn)行時(shí)都有一個(gè)關(guān)聯(lián)的鎖。這個(gè)鎖可通過(guò)為方法添加關(guān)鍵字 synchronized 來(lái)獲得。這樣,修訂過(guò)的 Account 對(duì)象(如下所示)將不會(huì)遭受像數(shù)據(jù)損壞這樣的錯(cuò)誤:




















對(duì)一個(gè)銀行中的多項(xiàng)活動(dòng)進(jìn)行同步處理:
deposit() 和 withdraw() 函數(shù)都需要這個(gè)鎖來(lái)進(jìn)行操作,所以當(dāng)一個(gè)函數(shù)運(yùn)行時(shí),另一個(gè)函數(shù)就被阻塞。請(qǐng)注意, checkBalance() 未作更改,它嚴(yán)格是一個(gè)讀函數(shù)。因?yàn)?checkBalance() 未作同步處理,所以任何其他方法都不會(huì)阻塞它,它也不會(huì)阻塞任何其他方法,不管那些方法是否進(jìn)行了同步處理.
關(guān)于synchronized
1、synchronized關(guān)鍵字的作用域有二種:
1)是某個(gè)對(duì)象實(shí)例內(nèi),synchronized aMethod(){}可以防止多個(gè)線程同時(shí)訪問(wèn)這個(gè)對(duì)象的synchronized方法(如果一個(gè)對(duì)象有多個(gè)synchronized方法,只要一個(gè)線程訪問(wèn)了其中的一個(gè)synchronized方法,其它線程不能同時(shí)訪問(wèn)這個(gè)對(duì)象中任何一個(gè)synchronized方法)。這時(shí),不同的對(duì)象實(shí)例的synchronized方法是不相干擾的。也就是說(shuō),其它線程照樣可以同時(shí)訪問(wèn)相同類的另一個(gè)對(duì)象實(shí)例中的synchronized方法;
2)是某個(gè)類的范圍,synchronized static aStaticMethod{}防止多個(gè)線程同時(shí)訪問(wèn)這個(gè)類中的synchronized static 方法。它可以對(duì)類的所有對(duì)象實(shí)例起作用。
2、除了方法前用synchronized關(guān)鍵字,synchronized關(guān)鍵字還可以用于方法中的某個(gè)區(qū)塊中,表示只對(duì)這個(gè)區(qū)塊的資源實(shí)行互斥訪問(wèn)。用法是: synchronized(this){/*區(qū)塊*/},它的作用域是當(dāng)前對(duì)象;
3、synchronized關(guān)鍵字是不能繼承的,也就是說(shuō),基類的方法synchronized f(){} 在繼承類中并不自動(dòng)是synchronized f(){},而是變成了f(){}。繼承類需要你顯式的指定它的某個(gè)方法為synchronized方法;