資源描述:
《張孝祥多線程文檔》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在教育資源-天天文庫。
1、北京傳智播客教育www.itcast.cn傳統(tǒng)線程機制的回顧創(chuàng)建線程的兩種傳統(tǒng)方式在Thread子類覆蓋的run方法中編寫運行代碼涉及一個以往知識點:能否在run方法聲明上拋出InterruptedException異常,以便省略run方法內(nèi)部對Thread.sleep()語句的try…catch處理?在傳遞給Thread對象的Runnable對象的run方法中編寫代碼總結(jié):查看Thread類的run()方法的源代碼,可以看到其實這兩種方式都是在調(diào)用Thread對象的run方法,如果Thread類的
2、run方法沒有被覆蓋,并且為該Thread對象設(shè)置了一個Runnable對象,該run方法會調(diào)用Runnable對象的run方法。問題:如果在Thread子類覆蓋的run方法中編寫了運行代碼,也為Thread子類對象傳遞了一個Runnable對象,那么,線程運行時的執(zhí)行代碼是子類的run方法的代碼?還是Runnable對象的run方法的代碼?涉及到的一個以往知識點:匿名內(nèi)部類對象的構(gòu)造方法如何調(diào)用父類的非默認(rèn)構(gòu)造方法。定時器的應(yīng)用Timer類TimerTask類北京傳智播客教育www.itcast.
3、cn線程的同步互斥與通信使用synchronized代碼塊及其原理使用synchronized方法分析靜態(tài)方法所使用的同步監(jiān)視器對象是什么?wait與notify實現(xiàn)線程間的通信北京傳智播客教育www.itcast.cn線程的同步互斥的圖文解說北京傳智播客教育www.itcast.cn多個線程訪問共享對象和數(shù)據(jù)的方式如果每個線程執(zhí)行的代碼相同,可以使用同一個Runnable對象,這個Runnable對象中有那個共享數(shù)據(jù),例如,買票系統(tǒng)就可以這么做。如果每個線程執(zhí)行的代碼不同,這時候需要用不同的Run
4、nable對象,有如下兩種方式來實現(xiàn)這些Runnable對象之間的數(shù)據(jù)共享:將共享數(shù)據(jù)封裝在另外一個對象中,然后將這個對象逐一傳遞給各個Runnable對象。每個線程對共享數(shù)據(jù)的操作方法也分配到那個對象身上去完成,這樣容易實現(xiàn)針對該數(shù)據(jù)進(jìn)行的各個操作的互斥和通信。將這些Runnable對象作為某一個類中的內(nèi)部類,共享數(shù)據(jù)作為這個外部類中的成員變量,每個線程對共享數(shù)據(jù)的操作方法也分配給外部類,以便實現(xiàn)對共享數(shù)據(jù)進(jìn)行的各個操作的互斥和通信,作為內(nèi)部類的各個Runnable對象調(diào)用外部類的這些方法。上面兩
5、種方式的組合:將共享數(shù)據(jù)封裝在另外一個對象中,每個線程對共享數(shù)據(jù)的操作方法也分配到那個對象身上去完成,對象作為這個外部類中的成員變量或方法中的局部變量,每個線程的Runnable對象作為外部類中的成員內(nèi)部類或局部內(nèi)部類。總之,要同步互斥的幾段代碼最好是分別放在幾個獨立的方法中,這些方法再放在同一個類中,這樣比較容易實現(xiàn)它們之間的同步互斥和通信。極端且簡單的方式,即在任意一個類中定義一個static的變量,這將被所有線程共享。北京傳智播客教育www.itcast.cnThreadLocal實現(xiàn)線程范圍
6、的共享變量見下頁的示意圖和輔助代碼解釋ThreadLocal的作用和目的:用于實現(xiàn)線程內(nèi)的數(shù)據(jù)共享,即對于相同的程序代碼,多個模塊在同一個線程中運行時要共享一份數(shù)據(jù),而在另外線程中運行時又共享另外一份數(shù)據(jù)。每個線程調(diào)用全局ThreadLocal對象的set方法,就相當(dāng)于往其內(nèi)部的map中增加一條記錄,key分別是各自的線程,value是各自的set方法傳進(jìn)去的值。在線程結(jié)束時可以調(diào)用ThreadLocal.clear()方法,這樣會更快釋放內(nèi)存,不調(diào)用也可以,因為線程結(jié)束后也可以自動釋放相關(guān)的Thr
7、eadLocal變量。ThreadLocal的應(yīng)用場景:訂單處理包含一系列操作:減少庫存量、增加一條流水臺賬、修改總賬,這幾個操作要在同一個事務(wù)中完成,通常也即同一個線程中進(jìn)行處理,如果累加公司應(yīng)收款的操作失敗了,則應(yīng)該把前面的操作回滾,否則,提交所有操作,這要求這些操作使用相同的數(shù)據(jù)庫連接對象,而這些操作的代碼分別位于不同的模塊類中。銀行轉(zhuǎn)賬包含一系列操作:把轉(zhuǎn)出帳戶的余額減少,把轉(zhuǎn)入帳戶的余額增加,這兩個操作要在同一個事務(wù)中完成,它們必須使用相同的數(shù)據(jù)庫連接對象,轉(zhuǎn)入和轉(zhuǎn)出操作的代碼分別是兩個不
8、同的帳戶對象的方法。例如Strut2的ActionContext,同一段代碼被不同的線程調(diào)用運行時,該代碼操作的數(shù)據(jù)是每個線程各自的狀態(tài)和數(shù)據(jù),對于不同的線程來說,getContext方法拿到的對象都不相同,對同一個線程來說,不管調(diào)用getContext方法多少次和在哪個模塊中g(shù)etContext方法,拿到的都是同一個。實驗案例:定義一個全局共享的ThreadLocal變量,然后啟動多個線程向該ThreadLocal變量中存儲一個隨機值,接著各個線程調(diào)用另外其他多個類