未完待續(xù)。
閱讀幫助
本文運(yùn)用《如何閱讀一本書(shū)》的學(xué)習(xí)方法進(jìn)行學(xué)習(xí)。
P15 表示對(duì)于書(shū)的第15頁(yè)。
Java并發(fā)編程實(shí)戰(zhàn)簡(jiǎn)稱(chēng)為并發(fā)書(shū)或者該書(shū)之類(lèi)的。
熟能生巧,不斷地去理解,就像欣賞一部喜歡的電影,時(shí)不時(shí)就再看一遍,甚至把劇本下下來(lái)通讀。
思想
1、雖然現(xiàn)在都是分布式系統(tǒng),日新月異,但是代碼層面的并發(fā)思想是可以學(xué)習(xí)借鑒的,在不同的層面上使用并發(fā)的設(shè)計(jì)理念。
2、本地上的并發(fā)安全加鎖運(yùn)行起來(lái)是比分布式redis鎖快的,比較redis鎖的交互需要通信,本地是代碼層級(jí)的執(zhí)行,還有就是用redis鎖主要是我們現(xiàn)在是分布式系統(tǒng),該鎖的作用可能作用的范圍是這幾臺(tái)服務(wù)器,用于比如重試、扣庫(kù)存之類(lèi)的,那么加鎖的層級(jí)就必須是像redis這樣公用的鎖平臺(tái)才行。
3、代碼的執(zhí)行效率問(wèn)題,如果能在代碼層級(jí)范圍來(lái)操作并發(fā)執(zhí)行安全的代碼操作,即并發(fā)寫(xiě)得好,這樣就能提高單臺(tái)服務(wù)器的服務(wù)能力,比如1000tps和200tps的區(qū)別,還有就是分布式服務(wù)的線性擴(kuò)展能力,不過(guò)這方面應(yīng)該是分布式的架構(gòu)問(wèn)題,但回到第一個(gè)思想上來(lái),我們可以學(xué)習(xí)其思想。
檢視閱讀
1 有系統(tǒng)的略讀(目錄,索引,關(guān)鍵字段等,已完成)
2 粗淺的閱讀(不求甚解的全本閱讀,已完成)
有個(gè)不合格的地方是閱讀效率不高,耗費(fèi)時(shí)間太長(zhǎng),不能在有效的時(shí)間內(nèi)看完,主動(dòng)性閱讀只能算及格,還不是很投入式,閱讀的主次不分,不能對(duì)需要花費(fèi)心思理解的部分多花時(shí)間加深理解,而對(duì)于可以略讀的部分加快閱讀速度(當(dāng)然,對(duì)于這種實(shí)用技術(shù)書(shū)一般都是重點(diǎn))。
前言部分提供了這本書(shū)的各個(gè)章節(jié)的大體介紹,每個(gè)章節(jié)分屬的部分。
自我要求的4個(gè)基本問(wèn)題
1、這本書(shū)在談些什么
什么是并發(fā),為什么要用到并發(fā),以及如何使用并發(fā),特別是編寫(xiě)性能更好的并發(fā)代碼。還有一部分并發(fā)代碼如何測(cè)試的內(nèi)容以及了解jvm的內(nèi)存模型。
2、作者的主要想法、聲明、和論點(diǎn)。
作者想通過(guò)這本書(shū)教會(huì)學(xué)者如何更好更準(zhǔn)確的編寫(xiě)并發(fā)代碼,關(guān)于并發(fā)代碼的核心思想其實(shí)有三個(gè)方式解決問(wèn)題:
一是不在線程間共享狀態(tài)變量,即不用。
1、線程封閉
2、棧封閉(局部變量)
3、ThreadLocal(線程本地變量)類(lèi)存儲(chǔ)。
最常見(jiàn)的ThreadLocal使用場(chǎng)景為用來(lái)解決數(shù)據(jù)庫(kù)連接、Session管理 。
二是將狀態(tài)變量修改為不可變的變量,即保證不變性。
滿(mǎn)足以下條件構(gòu)造不變性對(duì)象:
1、對(duì)象創(chuàng)建以后其狀態(tài)(對(duì)象的成員變量、或者說(shuō)域)就不能修改。(賦值的時(shí)候注意對(duì)象賦值是賦值地址(引用傳遞),所以要通過(guò)copy對(duì)象內(nèi)容創(chuàng)建新對(duì)象賦值)。
2、對(duì)象的域都是final類(lèi)型。
3、對(duì)象是正確構(gòu)建的(在對(duì)象的創(chuàng)建期間,this引用沒(méi)有逸出)。
當(dāng)多個(gè)線程同時(shí)訪問(wèn)同一個(gè)資源,并且其中的一個(gè)或者多個(gè)線程對(duì)這個(gè)資源進(jìn)行了寫(xiě)操作,才會(huì)產(chǎn)生競(jìng)態(tài)條件。多個(gè)線程同時(shí)讀同一個(gè)資源不會(huì)產(chǎn)生競(jìng)態(tài)條件。
注意:
A(譯者注:注意,“不變”(Immutable)和“只讀”(Read Only)是不同的。當(dāng)一個(gè)變量是“只讀”時(shí),變量的值不能直接改變,但是可以在其它變量發(fā)生改變的時(shí)候發(fā)生改變。比如,一個(gè)人的出生年月日是“不變”屬性,而一個(gè)人的年齡便是“只讀”屬性,但不是“不變”屬性。隨著時(shí)間的變化,一個(gè)人的年齡會(huì)隨之發(fā)生變化,而一個(gè)人的出生年月日則不會(huì)變化。這就是“不變”和“只讀”的區(qū)別。(摘自《Java與模式》第34章))
B 只要不是帶有屬性值的引用類(lèi)型對(duì)象都不會(huì)因?yàn)樵局蹈淖兌鴮?dǎo)致對(duì)象的final域也改變.
三是如果一定要訪問(wèn)到可變的共享狀態(tài)變量時(shí)使用同步,即加鎖同步代碼。
juc并發(fā)包的類(lèi)和加鎖同步。
四是安全發(fā)布對(duì)象
要安全地發(fā)布一個(gè)對(duì)象,對(duì)象的引用以及對(duì)象的狀態(tài)(成員屬性)必須同時(shí)對(duì)其他線程可見(jiàn)??赏ㄟ^(guò)4種方式安全發(fā)布:
-
在靜態(tài)初始化函數(shù)中初始化一個(gè)對(duì)象引用。(或者靜態(tài)初始化塊)
//靜態(tài)的初始化器,由于在JVM內(nèi)部存在著同步機(jī)制,保證其安全發(fā)布。 public staitc Holder holder = new Holder(42); 將對(duì)象的引用保存在volatile類(lèi)型的域或者AtomicReferance對(duì)象中(可見(jiàn)性)。
將對(duì)象的引用保存到某個(gè)正確構(gòu)造對(duì)象的final類(lèi)型域中(不變性)。
將對(duì)象的引用保存到一個(gè)由鎖保護(hù)的域中(直接加鎖同步)。
3、這本書(shū)是否有道理?有合理性?
有道理且合理,不過(guò)有些還沒(méi)弄明白,還有就是目前高并發(fā)的技術(shù)不止是在代碼層面的編寫(xiě),還有分布式應(yīng)用等。
4、這本書(shū)跟我的關(guān)系和意義?
提高我的并發(fā)代碼的理解領(lǐng)悟和編寫(xiě)能力,理解并發(fā)處理的思想,通過(guò)并發(fā)可以更高效地發(fā)揮代碼的效率。
分析閱讀
核心:提出問(wèn)題,找出答案
一、在談些什么
1、根據(jù)書(shū)的種類(lèi)和主題分類(lèi)
實(shí)用性書(shū),工具書(shū)類(lèi)型。
2、簡(jiǎn)短概況本書(shū)內(nèi)容
合理的配置線程和編寫(xiě)并發(fā)代碼可以更高效率地提高多核系統(tǒng)的效率,提高資源利用率和系統(tǒng)吞吐率,而編寫(xiě)并發(fā)代碼的原則是能不在線程間共享狀態(tài)變量盡量不共享;如果需要共享則最好是不變的狀態(tài)變量;上面這兩種都可以有效避免線程間的問(wèn)題,實(shí)在不能避免,則在編寫(xiě)并發(fā)代碼時(shí)用上jdk api里提供的juc包里各種線程安全類(lèi),并注意并發(fā)線程的活躍性、性能、和測(cè)試問(wèn)題。
//待補(bǔ)充
3、按順序和關(guān)聯(lián)性列舉全書(shū)大綱(簡(jiǎn)介描述)和各個(gè)部分大綱
先大后小,先粗后細(xì),搭出骨架后再充填細(xì)的部分,分起碼兩層分部結(jié)構(gòu),一,一之一,一之二等
一、并發(fā)理論基礎(chǔ)及規(guī)則(2-3章)
避免并發(fā)危險(xiǎn)
-
構(gòu)造線程安全的類(lèi)
加鎖機(jī)制:
1、內(nèi)置鎖
同步代碼塊的鎖就是方法調(diào)用所在的對(duì)象,該類(lèi)的實(shí)例(所以不同實(shí)例可以有多個(gè)鎖);靜態(tài)同步方法的鎖是以類(lèi)Class作為鎖,所以只有一把。
2、重入
鎖是可重入的,獲取鎖的操作的粒度是線程而不是調(diào)用(即不是每次調(diào)用就獲取一此鎖,如果該線程已經(jīng)持有了,則他可以重入該方法,如果不可重入,則將因?yàn)楂@取不到鎖而永遠(yuǎn)停頓下去(已經(jīng)持有了))。
注意:能不能進(jìn)入某個(gè)同步方法取決于是否取到該方法的的鎖,如果是實(shí)例鎖對(duì)象,則不同實(shí)例的方法調(diào)用操作分別獲取不同的鎖,并不會(huì)因?yàn)槭峭粋€(gè)Class類(lèi)而阻塞,只有靜態(tài)類(lèi)才有且只有一個(gè)鎖對(duì)象。
3、盡量縮小同步代碼塊的作用范圍。
4、不可能三角:安全性、簡(jiǎn)單性和性能是不能同時(shí)達(dá)到的,而安全性是必須的,所以簡(jiǎn)單些和性能之間存在著相互制約,一定不要盲目地為了性能而犧牲簡(jiǎn)單性(可能破壞安全性)。
5、持有鎖時(shí)間過(guò)長(zhǎng)則會(huì)帶來(lái)活躍性或性能問(wèn)題。因此,當(dāng)執(zhí)行時(shí)間較長(zhǎng)的計(jì)算或者無(wú)法快速完成的操作(I/O),一定不要持有鎖。
6、自己構(gòu)建線程安全類(lèi)和juc類(lèi)庫(kù)來(lái)構(gòu)建并發(fā)應(yīng)用程序。
驗(yàn)證線程安全
如何共享和發(fā)布對(duì)象?
發(fā)布和逸出 。當(dāng)把一個(gè)對(duì)象傳遞給某個(gè)外部方法時(shí)(public),就相當(dāng)于發(fā)布了這個(gè)對(duì)象。發(fā)布一個(gè)引用出去就可能帶來(lái)安全性問(wèn)題,因?yàn)樵撘眯畔⒁莩隽?。所以我們使用封裝的最主要原因就是封裝能夠使得對(duì)程序的正確性進(jìn)行分析變得可能,減少可能的破壞設(shè)計(jì)約束條件。
線程封閉:不共享數(shù)據(jù),就不會(huì)有并發(fā)問(wèn)題。局部變量(即棧封閉)和ThreadLocal類(lèi)是線程封閉的,線程封閉是在程序設(shè)計(jì)中的一個(gè)考慮因素(Swing、JDBC的Connection對(duì)象)
二、如何組合線程安全類(lèi)juc模塊介紹(4-5章)
-
線程安全組合
設(shè)計(jì)線程安全類(lèi)的三個(gè)基本要素:
- 找出構(gòu)成對(duì)象狀態(tài)的所以變量。
- 找出約束狀態(tài)變量的不變性條件。
- 簡(jiǎn)歷對(duì)象狀態(tài)(變量)的并發(fā)訪問(wèn)管理策略(形成正式文檔)。
實(shí)例封閉:將數(shù)據(jù)封裝在對(duì)象內(nèi)部,可以將數(shù)據(jù)的訪問(wèn)限制在對(duì)象的方法上,從而更容易保證現(xiàn)場(chǎng)在訪問(wèn)數(shù)據(jù)時(shí)總能持有正確的鎖。(即把對(duì)象的數(shù)據(jù)訪問(wèn)收斂到方法上,這樣只需要對(duì)訪問(wèn)該方法加鎖同步就能保證對(duì)其訪問(wèn)的線程安全)
- 線程安全容器類(lèi)
- 線程安全同步工具類(lèi)
三、結(jié)構(gòu)化并發(fā)應(yīng)用程序——如何利用線程提高并發(fā)應(yīng)用程序的吞吐量或響應(yīng)性(6-9章)
- 如何識(shí)別可并行執(zhí)行的任務(wù),以及如何在任務(wù)執(zhí)行框架中執(zhí)行任務(wù)。
- 健壯的并發(fā)應(yīng)用程序的關(guān)鍵——如何實(shí)現(xiàn)取消和關(guān)閉線程執(zhí)行任務(wù)。
- 線程池的使用
- 如何提高單線程子系統(tǒng)的響應(yīng)性——圖形用戶(hù)界面應(yīng)用程序
四、活躍性、性能與測(cè)試——確保并發(fā)程序執(zhí)行預(yù)期任務(wù),獲得理想性能(10-12章)
- 如何避免活躍性故障
- 如何提高并發(fā)代碼的性能和可伸縮性。
- 測(cè)試并發(fā)代碼的技術(shù)
五、高級(jí)主題—— (13-16章)
- 顯示鎖
- 原子變量
- 非阻塞算法
- 自定義同步工具類(lèi)
//待補(bǔ)充
4、作者想要我做什么或者想要解決什么問(wèn)題。
理解和領(lǐng)悟并發(fā)的思想和其優(yōu)缺點(diǎn),并教我們?cè)趺淳帉?xiě)優(yōu)秀的并發(fā)代碼。
//待補(bǔ)充
二、詮釋這本書(shū)內(nèi)容
5、關(guān)鍵字,與作者達(dá)成共識(shí)
安全性:永遠(yuǎn)不會(huì)發(fā)生糟糕的事情。
活躍性:某件正確的事情最終會(huì)發(fā)生。(當(dāng)某個(gè)操作無(wú)法繼續(xù)執(zhí)行下去時(shí),就會(huì)發(fā)生活躍性問(wèn)題,如死鎖、饑餓、活鎖)
性能:包含多個(gè)方面,如服務(wù)時(shí)間過(guò)長(zhǎng)(提供的服務(wù)接口響應(yīng)太慢);響應(yīng)不靈敏;吞吐率過(guò)低;資源消耗過(guò)高;可伸縮性降低等。
線程、鎖、
競(jìng)態(tài)條件:由于不恰當(dāng)?shù)膱?zhí)行時(shí)序而出現(xiàn)不正確的結(jié)果。最常見(jiàn)的競(jìng)態(tài)條件類(lèi)型(先檢查后執(zhí)行:CHECK-THEN-ACT)
最低安全性:線程在沒(méi)有同步情況下讀取變量時(shí),可能會(huì)得到一個(gè)失效值,但至少不是隨機(jī)數(shù),而是之前線程設(shè)置的值,這種安全保證稱(chēng)為最低安全性。(最低安全性不適用于非volatile類(lèi)型的64位數(shù)值變量--> double、long,因?yàn)閖vm運(yùn)行將64位的讀或?qū)懖僮鞣纸獬蓛蓚€(gè)32位的讀或?qū)懖僮鳎?/p>
依賴(lài)狀態(tài)的操作:即某個(gè)操作包含基于狀態(tài)的先驗(yàn)條件(如隊(duì)列刪除前判空等),那么這個(gè)操作就是依賴(lài)狀態(tài)的操作。要實(shí)現(xiàn)某個(gè)等待先驗(yàn)條件為真時(shí)才執(zhí)行的操作,可以通過(guò)(Blocking Queue , Semaphore 實(shí)現(xiàn))。
//待補(bǔ)充
6、重要句子即作者的主旨
- 要編寫(xiě)線程安全的代碼,其核心在于要對(duì)狀態(tài)訪問(wèn)操作進(jìn)行管理,特別是對(duì)共享的(shared)和可變的(mutable)狀態(tài)的訪問(wèn)。對(duì)象的狀態(tài)(主要在實(shí)例或靜態(tài)域)中的數(shù)據(jù)。
- 共享:多個(gè)線程訪問(wèn)。
- 可變:生命周期內(nèi)可以發(fā)生變化。
- 正確的編程方法:首先使代碼正確運(yùn)行,然后再提高代碼的速度。(先完成,再優(yōu)化)
- 線程安全性定義:當(dāng)多個(gè)線程訪問(wèn)某個(gè)類(lèi)時(shí),這個(gè)類(lèi)始終都能表現(xiàn)出正確的行為,說(shuō)明這個(gè)類(lèi)是線程安全的。
無(wú)狀態(tài)對(duì)象一定是線程安全的。(因?yàn)樗炔话魏斡颍膊话魏螌?duì)其他類(lèi)的類(lèi)中域的引用。)
- 盡可能使用現(xiàn)有的線程安全對(duì)象(如AtomicLong)來(lái)管理類(lèi)的狀態(tài)。如往無(wú)狀態(tài)的類(lèi)中添加一個(gè)有線程安全的對(duì)象來(lái)管理狀態(tài)的類(lèi)時(shí),這個(gè)類(lèi)仍然是安全的。
- 要保持狀態(tài)的一致性,就需要在單個(gè)原子操作中更新所有相關(guān)的狀態(tài)變量。(即使這些狀態(tài)變量各自都是線程安全的,也要保證所以的狀態(tài)操作在同一個(gè)原子操作中,相當(dāng)于一個(gè)事務(wù))
- 正如“除非需要更高的可見(jiàn)性,否則將所有的域(屬性)都聲明為私有域是一個(gè)良好的編程習(xí)慣”,“除非需要某個(gè)域是可變的,否則應(yīng)將其聲明為final域”也是一個(gè)良好的編程習(xí)慣。
- 任何線程都可以在不需要額外同步的情況下安全地訪問(wèn)不可變對(duì)象,即使在發(fā)布這些對(duì)象時(shí)沒(méi)有使用同步(疑問(wèn):我的理解是這些對(duì)象不可變,所以只發(fā)布一次;或者是這些對(duì)象內(nèi)部不可變對(duì)象的三個(gè)條件,所以不會(huì)有不確定性)。
- 實(shí)例封閉是構(gòu)建線程安全類(lèi)的最簡(jiǎn)單方式。即:將數(shù)據(jù)封裝在對(duì)象內(nèi)部,可以將數(shù)據(jù)的訪問(wèn)限制在對(duì)象的方法上,從而更容易確保線程在訪問(wèn)數(shù)據(jù)時(shí)總能持有正確的鎖。
實(shí)例封閉實(shí)例:
@ThreadSafe
public class TestBeanSet {
@GuardedBy("this")
private final Set<TestBean> mySet = new HashSet<TestBean>();
public synchronized void addTestBean(TestBean t) {
mySet.add(t);
}
public synchronized boolean containsTestBean(TestBean t) {
return mySet.contains(t);
}
}
- 如果不了解對(duì)象的不變性條件(取值不能為負(fù)數(shù))與后驗(yàn)條件(取值變化范圍在兩個(gè)域值的范圍區(qū)間,如范圍的上下界,下界值應(yīng)該小于等于上界值),那么就不能確保線程安全性。要滿(mǎn)足在狀態(tài)變量的有效值或者狀態(tài)轉(zhuǎn)換上的各種約束條件,就需要借助于原子性和封裝性(<u>怎么借助封裝性?</u>)。
- 基于狀態(tài)的先驗(yàn)條件判斷的操作稱(chēng)為依賴(lài)狀態(tài)的操作。如判空移除元素等。這種比較多見(jiàn)與生存消費(fèi)模式下的操作,常見(jiàn)有Blocking Queue 或 Semaphore 。
//待補(bǔ)充
7、找出作者的的論述,總結(jié)作者的想法、看法
歸納法或者演繹法
并發(fā)程序中使用和共享對(duì)象時(shí)的實(shí)用策略,有四:
1、線程封閉。線程封閉的對(duì)象只能由一個(gè)線程擁有,對(duì)象被封閉在該線程中,不共享,則線程安全使用對(duì)象。
2、只讀共享(即不可變對(duì)象)。在沒(méi)有額外的同步情況下,共享的只讀對(duì)象可以由多個(gè)線程并發(fā)訪問(wèn),但任何線程都不能修改它(有的情況下可以新建一個(gè)不可變對(duì)象去替換它)。共享的只讀對(duì)象包括不可變對(duì)象和事實(shí)不可變對(duì)象。
3、線程安全共享(經(jīng)過(guò)線程安全同步的數(shù)據(jù)結(jié)構(gòu)或者類(lèi),如currenthashmap等juc包下的線程安全類(lèi))。線程安全的對(duì)象在其內(nèi)部實(shí)現(xiàn)同步,因此多個(gè)線程可以通過(guò)對(duì)象的公共接口(get/set)來(lái)進(jìn)行訪問(wèn)而不需要進(jìn)一步同步(加鎖等操作)。
4、保護(hù)對(duì)象。被保護(hù)的對(duì)象只能通過(guò)持有特定的鎖來(lái)訪問(wèn)。保護(hù)對(duì)象包括封裝在其他線程安全對(duì)象中的對(duì)象(是什么?),以及已發(fā)布的并且有某個(gè)特定鎖保護(hù)的對(duì)象(顯示鎖,@GuardedBy)。
//待補(bǔ)充
8、作者要我們這么做的目的(解決了哪些問(wèn)題)
寫(xiě)出線程安全的類(lèi)。
三、評(píng)論這本書(shū)
前提條件:完成大綱架構(gòu)
在評(píng)論時(shí)能區(qū)分真正的知識(shí)和個(gè)人的觀點(diǎn)的不同
批評(píng)時(shí)要能證明作者的知識(shí)不足或錯(cuò)誤、不合邏輯、分析與理由不完整等。
自己的評(píng)論,或者讀后感。
一些知識(shí)整理
1、并發(fā)中的單例模式寫(xiě)法:
java并發(fā)中的延遲初始化 推薦這個(gè)
2、高效是指能在串行性和異步性之間找到合理的平衡。
3、讀取volatile 變量開(kāi)銷(xiāo)只比讀取非volatile變量的開(kāi)銷(xiāo)略高一點(diǎn),因此遠(yuǎn)低于加鎖的變量。volatile的正確使用方式包括:只能確??梢?jiàn)性,以及標(biāo)識(shí)程序生命周期事件的發(fā)生(如初始化或關(guān)閉)。還需要尋找一下程序中volatile的使用。
原子變量(atomicInteger等)是一種更好的volatile。
滿(mǎn)足以下三個(gè)條件,才應(yīng)該使用volatile變量:
- 對(duì)變量的寫(xiě)入操作不依賴(lài)變量的當(dāng)前值,或者確保只有單個(gè)線程更新變量的值(set方法是synchronized的同步方法)
- 該變量不會(huì)與其它狀態(tài)變量一起納入不變性條件中。(否則可見(jiàn)性就沒(méi)有意義,因?yàn)樗绻緛?lái)就不變,那不需要可見(jiàn)性啊)
- 在訪問(wèn)變量時(shí)不需要加鎖。
4、如果想在構(gòu)造函數(shù)中注冊(cè)一個(gè)事件監(jiān)聽(tīng)器或啟動(dòng)線程,可以使用一個(gè)私有的構(gòu)造函數(shù)和一個(gè)公共的工廠方法。還需要理解下!
疑問(wèn)解答
1、p1中的粗粒度通信機(jī)制交換數(shù)據(jù),包括:套接字、信號(hào)處理器、共享內(nèi)存、信號(hào)量以及文件等,里面名稱(chēng)的意思和通信機(jī)制一般是什么?
2、時(shí)間分片(time slicing)?
A:指每個(gè)CPU會(huì)把其時(shí)間進(jìn)行分配,每個(gè)程序都有機(jī)會(huì)占有一個(gè)或多個(gè)片段,去執(zhí)行自己的任務(wù)。
3、什么是馮諾依曼計(jì)算機(jī)?
4、什么是句柄??jī)?nèi)存句柄?文件句柄?
5、上下文切換會(huì)帶來(lái)多大的開(kāi)銷(xiāo)呢?
6、抽象和封裝會(huì)降低程序的性能?是拿來(lái)跟面向過(guò)程(C)比?
7、volatile的使用?
8、發(fā)布和逸出需要仔細(xì)了解下?p34:不正確構(gòu)造?
9、p25:搞不清楚這兩個(gè)同步代碼塊不會(huì)因?yàn)橹虚g釋放鎖而導(dǎo)致失去鎖,應(yīng)用安全性不能滿(mǎn)足么?
10、為什么final類(lèi)型的域使用越多,就越能簡(jiǎn)化對(duì)象可能狀態(tài)的分析過(guò)程?或者說(shuō)final 域?yàn)槭裁茨鼙WC是不變的?如果是個(gè)fina對(duì)象呢,對(duì)象里面的屬性也必須是final的才能保證吧?
使用到并發(fā)的開(kāi)源代碼或組件
1、Swing 的用戶(hù)界面框架
2、Servlet
3、RMI(rpc)
4、Swing、JDBC學(xué)習(xí)線程封閉技術(shù)
5、連接池是線程安全的。
參考
《Java并發(fā)編程實(shí)戰(zhàn)》