多線程高並發編程總結


多線程

第一章

一。終止線程的三種方法:

1.使用退出標志,是縣城正常退出,也就是當run方法完成后線程終止。

2.stop不推薦

3.使用interrupt(打了一個停止標記,並不是真的停止線程)。

1)interrupt+throw new interruptexception(推薦使用,catch塊中還可以將異常向上拋,使線程停止的事件得以傳播。)

2) interrupt+return

 二。this.interrupted()和this.isInterrupted()

1)this.interrupted():測試當前線程是否已經是中斷狀態,執行后具有將狀態標志清除為false的功能。

2)測試線程Thread對象是否已經是中斷狀態,但不清除狀態標志。

 三。stop方法為什么不用?

1)已經作廢,因為如果強制讓線程停止則有可能使一些清理性的工作得不到完成。

2)另外一個情況就是對鎖定的對象鏡像了“解鎖”,導致數據得不到同步的處理,出現數據不一致的問題。

 四。suspend與resume的缺點:

1)獨占鎖

2)不同步

五。守護進程:保姆,提供便利服務,只要當前進程實例中存在任何一個非守護進程 沒有結束,守護進程就在工作,只有當最后一個非守護進程結束時,守護進程才隨着jvm一同結束工作。典型應用是GC

第二章

 

一。synchronized鎖重入:

自己可以再次獲取自己的內部鎖,比如有一條線程獲得了某個對象的鎖,此時這個對象鎖還沒有釋放,當其再次想要獲取這個對象的鎖的時候還是可以獲得的,如果不可鎖重入的話,就會造成死鎖。

二。出現異常,鎖自動釋放。

三。同步不具有繼承性

四。在使用同步synchronized(this)代碼塊時需要注意的是,當一個線程訪問object的一個synchronized同步代碼塊時,其他線程對同一個object中所有其他synchronized同步代碼塊的訪問將被阻塞,這說明synchronized使用的“對象監視器”是一個。

五。可以將this作為對象監視器,也可以將任意對象作為對象監視器。

六。synchroniezd(this)和synchronized同步方法的對象監視器都是對象本身。

七。鎖非this對象具有一定的優點:如果在一個類中有很多的synchronized方法,這時雖然能實現同步,但會受到阻塞,所以會影響運行效率;但如果使用同步代碼塊鎖非this對象,則synchronized(非this)代碼塊中的程序與同步方法是異步的,不與其他鎖this同步方法爭搶this鎖,則可以大大提高效率。

八。synchronized還可以用在static靜態方法上,對類進行加鎖。和對象鎖是不一樣的鎖。

九。同步synchronized(class)代碼塊的作用其實和synchronized static方法的作用一樣。

十。由於JVM中Strring常量池緩存的原因,在大多數的情況下,同步synchronized帶麥克都不使用String作為鎖對象,而改用其他,比如new Obj,但它不放入緩存池中。或者byte[] a=new byte[0];說明:零長度的byte數組對象創建起來將比任何對象都經濟――查看編譯后的字節碼:生成零長度的byte[]對象只需3條操作碼,而Object lock = new Object()則需要7行操作碼。

十一,只要對象不變,即使對象的屬性被改變,運行的結果還是同步。

十二。volatile:強制從公共堆棧中取得變量值,而不是從線程私有數據棧匯總取得變量的值。不支持原子性。

第三章 線程通信。

一。wait使線程停止運行,而notify使停止的線程繼續運行。在調用wait之前,線程必須獲得該對象的對象級別鎖,即只能在同步方法或同步塊中調用wait方法。在執行wait后,當前線程釋放鎖。如果調用wait時沒有持有適當的鎖,則拋出illegalMonitorStateException。notify調用沒有持有適當的鎖也會illegalMonitorStateException。

二。notify方法執行后並不立即釋放鎖,wait立即釋放。如果發出notify操作時沒有處於阻塞狀態中的線程,那么該命令會被忽略。

三。 線程切換:

 

1)新創建一個新的線程對象后,再調用它的star()方法,系統會為此線程分配CPU資源,使其處於Runnable (可運行)狀態,這是一個准備運行的階段。如果線程搶占到CPU資源,此線程就處於Running(運行)狀態。
2) Runnable狀態和Running狀態可相互切換,因為有可能線程運行一段時間后, 有其他高優先級的線程搶占了CPU資源,這時此線程就從Running狀態變成Runnable狀態。
線程進入Runnable狀態大體分為如下5種情況:
調用sleep)方法后經過的時間超過了指定的休眠時間。 
線程調用的阻塞IO已經返回,阻塞方法執行完畢。

線程成功地獲得了試圖同步的監視器。

線程正在等待某個通知,其他線程發出了通知。
處於掛起狀態的線程調用了resume恢復方法。
3) Blocked是阻塞的意思,例如遇到了一個IO操作,此時CPU處於空閑狀態,可能會轉而把CPU時間片分配給其他線程,這時也可以稱為“暫停”狀態。Blocked 狀態結束后,
進人Runnable狀態,等待系統重新分配資源。
出現阻塞的情況大體分為如下5種:

線程調用seep方法,主動放棄占用的處理器資源。

線程調用了阻塞式IO方法,在該方法返回前,該線程被阻塞。

線程試圖獲得一個同步監視器,但該同步監視器正被其他線程所持有。

線程等待某個通知。
程序調用了suspend 方法將該線程掛起。此方法容易導致死鎖,盡量避免使用該方法。

4) run(方法運行結束后進人銷毀階段,整個線程執行完畢。

   每個鎖對象都有兩個隊列,一個是就緒隊列,一個阻塞隊列。就緒隊列存儲了將要獲得鎖的線程,阻塞隊列存儲了被阻塞的線程。一個線程被喚醒后,才會進人就緒隊列,等待CPU的調度;反之,一個線程被wait后,就會進人阻塞隊列,等待下一次被喚醒。 

 四。

1.sleep方法不釋放鎖。notify必須執行完notify方法所在的同步synchronized代碼塊后才釋放鎖。

2.

1)執行完同步代碼塊就會釋放對象的鎖。

2)在執行同步代碼塊的過程中,遇到異常而導致線程終止,鎖也會被釋放。

3)在執行同步代碼塊的過程中,執行了鎖所屬對象的wait方法,這個過程會釋放對象鎖,而此線程對象會進入線程等待池中,等待被喚醒。

五。線程之間通信方式之:管道 pipeStream 4個類:PipeInputStream PipedReader

六。方法join:等待線程對象銷毀,具有使線程排隊運行的作用。有些類似同步的運行效果。join與synchronized的區別:join內部使用wait進行等待,而synchronize使用的是對象監視器原理同步。

七。join(long)和wait(long)的區別:方法join(long)功能內部是使用wait(long)來實現的,所以join方法具有釋放鎖的特點。

 

八。threadLocal類:主要解決的問題是每個線程綁定自己的值。每一個線程有自己的私有數據。

       InheritableThreadLocal可以在子進程中取得父進程繼承下來的值。

第四章 Lock

一。lock.lock待的線程持有了“對象監視器”,其他線程只有等待被釋放時再次爭搶。

二。借助condition對象可以實現多路通知的功能,也就是在一個lock對象里面可以創建多個condition(對象監視器)實例,線程對象可以注冊在指定的condition中,從而有選擇的進行線程通知,在調度上更靈活。在使用notify/notifyall方法進行通知時,被通知的線程時jvm隨機選擇的。但使用rerntrantlock結合Condition類是可以實現“選擇性通知”。synchronized相當於整個lock對象只有一個單一的condition對象,所有的線程都注冊在它一個對象上。

三。wait相當於condition的await。wait(long timeout)相當於await(long)。notify相當於condition的signal,notifyall相當於signalAll。

四。想要實現一對一通知,只需創建對於的condition即可。Lock lock=new ReentrantLock;Condiition condition=lock.newCondition;

五。公平鎖和非公平鎖,是否按照線程加鎖的順序。FIFO.創建鎖的時候可以用構造方法傳入。默認是非公平鎖。

六。使用condition可以實現線程的按順序執行。使用多個condition和一個變量,這個變量要一直改變使一個線程可以執行,其他線程等待。

七。讀寫鎖ReentrantReadWriteLock,提高代碼運行速度(在不需要操作實例變量的方法中)。讀操作相關的鎖,也稱共享索女,寫操作的鎖,也稱排它鎖。也就是讀讀不互斥,讀寫互斥。寫寫互斥。即多個線程可以同時讀取操作,但是同一時刻只允許一個Thread寫入操作。

第六七章 單例模式與多線程

一。使用DCL 雙檢查鎖機制來實現多線程環境中的延遲加載單例設計模式。

那么我們為什么要使用兩個if判斷這個對象當前是不是空的呢 ?因為當有多個線程同時要創建對象的時候,多個線程有可能都停止在第一個if判斷的地方,等待鎖的釋放,然后多個線程就都創建了對象,這樣就不是單例模式了,所以我們要用兩個if來進行這個對象是否存在的判斷。

其他方式:使用靜態內置類。使用靜態代碼塊。使用枚舉類:構造方法自動調用。

二。simpledateformat非線程安全。解決方法一:創建多個simpleDateFormat。二:threadLocal

Java並發編程的藝術:

一。synchronized和lock的區別和優勢

缺少了隱式獲取釋放鎖的便捷性,但是卻擁有了鎖獲取與釋放的可操作性、可中斷的獲取鎖以及超時獲取鎖等synchronized不具備的同步特性。

1)嘗試非阻塞地獲取鎖

2)能被中斷地獲取鎖

3)超時獲取鎖

二。abstractQueueSynchronizer隊列同步器,是用來構建鎖或其他同步組件的基礎框架。(不同類型的同步組件ReentrantLock、ReentrantReadWriteLock和CountDownLatch等)

三。concurrentHashMap:HashTable在競爭激烈的並發環境下表現出效率低下的原因是所有訪問HashTable的線程都必須競爭通一把鎖,假如有多把鎖,每一把鎖用於鎖容器其中一部分數據,那么當多線程訪問容器里不同數據段的數據時,線程間就不會存在鎖競爭,從而可以有效提高並發訪問下來,這就是concurrentHashMap的鎖分段技術。首先將數據分成一段一段存儲,然后每一段數據配一把鎖當一個線程占用鎖訪問期中一個段數據時,其他段的數據也能被其他線程訪問。

四。CountDownLatch()和CyclicBarrier

cyclicBarrier:讓一組線程到達一個屏障時被阻塞,知道最后一個線程到達屏障時,屏障才會開門,所有被屏障連接的線程才會繼續進行。

countDownLatch的計數器只能使用一次,而cyclicBarrier的計數器可以使用reset方法重置。

CountDownLatch:主要是-1操作,可以用在一個線程的n個步驟,也可以是n個線程。

semaphone:可以用來做流量控制,特別是公共資源有限的場景。比如數據庫連接。acquire獲取、release歸還。

線程間交換數據的Exchanger:用於線程間協作。線程間數據交換,它提供一個同步點,在這個同步點,兩個線程可以交換彼此的數據。如果一個線程先執行exchanger方法,它會一直等待第二個線程也執行,當兩個線程到達同步點時,這兩個線程就可以交換數據,將本線程生產出來的數據傳遞給對方。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM