溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

java并發(fā)的知識點有哪些

發(fā)布時間:2022-01-06 15:28:31 來源:億速云 閱讀:100 作者:iii 欄目:大數(shù)據(jù)

這篇文章主要講解了“java并發(fā)的知識點有哪些”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“java并發(fā)的知識點有哪些”吧!

一、基礎(chǔ)知識

1、currenThread() 方法可返回代碼段正在被哪個線程調(diào)用的信息

2、多線程兩種方式 集成Thread OR 實現(xiàn)Runable

3、isAlive() 的功能是判斷當(dāng)前線程是否處于活動狀態(tài)(活動狀態(tài)就是線程以啟動且尚未終止)

4、sleep()的作用是在指定的毫秒數(shù)內(nèi)讓“正在執(zhí)行的線程” 休眠(暫停執(zhí)行,釋放cpu 但不釋放鎖)

5、getId() 的作用是取得線程的唯一標識

6、inerrupt() 用來停止線程,但interrupt() 方法的使用效果并不像for+break 一樣,馬上就停止循環(huán)。調(diào)用interrupt() 方法緊緊在當(dāng)前線程中打了一個停止的標記,并不是停止線程。

7、判斷線程是否停止,Thread 提供了兩種方法 ,interrupted() :測試當(dāng)前線程是否已經(jīng)中斷(此方法執(zhí)行后會清除中斷狀態(tài))。 isInterruopted() :測試線程是否已經(jīng)中斷(執(zhí)行后不清楚狀態(tài)標志)。

8、可以用異常法來中斷線程(先判斷isInterruopted() 然后拋出異常)

9、如果線程處于sleep()狀態(tài),此時中斷線程,將拋出異常,并清除停止狀態(tài)值。

10、暴力停止線程的方法,stop() 停止線程是非常暴力的,目前已經(jīng)廢棄,因為強制停止線程有可能會導(dǎo)致一些清理性的工作無法完成。另外就是對鎖定的對象進行了“解鎖”,導(dǎo)致數(shù)據(jù)得不到同步處理,出現(xiàn)數(shù)據(jù)不一致的問題。

11、可以使用suspend() 方法暫停線程,使用resume() 方法恢復(fù)線程的執(zhí)行。此方法不釋放鎖,只釋放cpu。使用不當(dāng),極易造成公共的同步對象獨占,使得其他線程無法訪問公共同步對象。也有可能造成數(shù)據(jù)不同步的現(xiàn)象(加鎖就不會了)

12、yield() 方法的作用是放棄當(dāng)前CPU資源,將它讓給其他任務(wù)執(zhí)行。但放棄時間不確定,有可能剛剛放棄,又馬上獲得CPU時間片。

13、可以通過setPriority()方法設(shè)置線程的優(yōu)先級,優(yōu)先級越高就會越先被執(zhí)行。優(yōu)先級是可以被繼承的,優(yōu)先級具有隨機性(并不保證低優(yōu)先級一定在高優(yōu)先級后執(zhí)行)

14、守護線程是一種特殊的線程,它的特性有“陪伴” 的含義,當(dāng)前線程中不存在非守護線程了,則守護線程自動銷毀。典型的守護線程就是垃圾回收線程。

二、對象及變量的并發(fā)訪問

1、“非線程安全” 問題存在于 實例變量 中,如果是方法內(nèi)部的私有變量,則不存在非線程安全問題。

2、 synchronized 加在方法上獲得的是類鎖,不同的對象活動不同的鎖。但同類中其他線程可以異步調(diào)用非synchronized方法

3、synchronized 鎖重入,也就是使用synchronized 時,當(dāng)一個線程得到一個對象鎖后,再次請求此對象鎖時是可以再次得到該對象鎖。這也證明在一個synchronized 方法/塊的內(nèi)部調(diào)用本類其他synchronized 方法/塊時,是永遠可以得到鎖。

4、如果不可鎖重入,就會造成死鎖,可重入鎖也支持在父子類繼承。

5、當(dāng)一個線程執(zhí)行的代碼出現(xiàn)異常時,其所持有的鎖會自動釋放。

6、使用synchronized 關(guān)鍵字聲明方法同步時,從時間上看,弊端很明顯,解決這樣的問題可以使用synchronized 同步塊。

7、在使用同步synchronized (this) 代碼塊時需要注意,當(dāng)一個線程訪問Object 的一個synchronized(this) 同步塊時,其他線程對同一個Object中所有其他synchronized(this) 代碼塊訪問將被阻塞,這說明synchronized 使用的 對象監(jiān)視器 是一個。

8、和synchronized 方法一樣,synchronized (this) 代碼塊也是鎖定當(dāng)前對象的。

9、多線程調(diào)用同一個對象的不同名稱synchronized 同步方法或synchronized (this)同步代碼塊時,調(diào)用的效果就是按順序執(zhí)行,也就是同步阻塞的。

10、java還支持synchronized (非this對象),優(yōu)點就是同類中不與其他synchronized (非this對象)爭搶this鎖。 volatile 關(guān)鍵字的主要作用是使變量在多個線程間可見

11、synchronized ( x) 前提下,當(dāng)多個線程同時執(zhí)行synchronized (x){} 同步代碼塊時呈現(xiàn)同步效果。當(dāng)其他線程執(zhí)行x對象中synchronized同步方法時呈現(xiàn)同步效果。當(dāng)其他線程執(zhí)行x對象方法里的synchronized(this)代碼塊時也呈現(xiàn)同步效果

12、關(guān)鍵字synchronized 還可以應(yīng)用在static 靜態(tài)方法上,如果這樣寫,那是對當(dāng)前*.java 文件對應(yīng)的Class類進行持鎖,也就說所有產(chǎn)生的對象實例都是同步的。

13、如果有synchronized public static 和 synchronized public 兩種持有的鎖是不一樣的,一個是class鎖,一個是對象鎖

14、同步synchronized (class) 代碼塊的作用其實和 synchronized static 方法的作用一樣,都是獲得class鎖

15、將synchronized (String) 同步塊與string 聯(lián)合使用時,要注意常量池帶來的一些例外。相同字符獲得鎖有可能是一樣的

16、死鎖就是程序bug,在設(shè)計時就要避免雙方互相持有對方的鎖的情況??梢允褂肑DK自帶工具檢測是否死鎖的現(xiàn)象。使用JPS命令找到線程ID,jstack -l id 查看結(jié)果

17、volatile 關(guān)鍵字的主要作用是使變量在多個線程間可見。線程棧屬于每個線程私有的,使用volatile將強制性從公共堆棧中獲取值。

18、使用volatile關(guān)鍵字增加了實例變量在多個線程之間的可見性。但volatile關(guān)鍵字最致命的缺點是不支持原子性。不支持i++類似操作。

19、關(guān)鍵字volatile是線程同步的輕量級實現(xiàn),所以其性能肯定比synchronized 要好,并且volatile只能修飾于變量,而synchronized 可以修飾方法及代碼塊。隨著JDK新版本發(fā)布,synchronized 在執(zhí)行效率上得到很大提升。

20、多線程訪問volatile不會發(fā)生阻塞,而synchronized 會出現(xiàn)阻塞。

21、volatile能保證數(shù)據(jù)的可見性,但不能保證原子性;而synchronized 可以保證原子性也可以間接保證可見性,因為它會將私有內(nèi)存和公共內(nèi)存中的數(shù)據(jù)進行同步。

22、volatile關(guān)鍵字解決的是變量在多個線程之間的可見性;synchronized 關(guān)鍵字解決的是多個線程之間訪問資源的同步性;

23、原子類操作可以使用AtomicInteger.incrementAndGet()等

三、線程間通信

1、wait() 方法作用是使當(dāng)前執(zhí)行代碼的線程等待,wait()方法是Object類的方法,該方法用來將當(dāng)前線程置入 “預(yù)執(zhí)行隊列”中,并且在wait()所在的代碼處停止執(zhí)行,直到接到通知或者被中斷為止。再調(diào)用wait()前,線程必須獲得該對象的對象級別鎖,即只能在同步方法或者同步塊中調(diào)用wait()方法。在執(zhí)行wait()方法后,當(dāng)前線程釋放鎖。再從wait()返回前,線程與其他線程競爭重新獲得鎖。如果調(diào)用wait()時沒有持有適當(dāng)?shù)逆i,則拋出IllegalMonitorStateException,它是runtimeException的一個字類,因此,不需要try-catch

2、 notify()方法也要在同步方法或同步塊中調(diào)用,即在調(diào)用前,線程也必須獲得該對象的對象級別的鎖。如果調(diào)用notify()沒有獲得適當(dāng)?shù)逆i,也會拋出IllegalMonitorStateException異常。該方法用來通知那些有可能等待該對象的對象鎖的其他線程,如果有多個線程等待,則由線程規(guī)劃器隨機挑選其中一個呈wait狀態(tài)的對象(線程級別越高獲得幾率越大),對其進行nontify()通知,并使其獲得對象鎖。

3、 在執(zhí)行notify()后,當(dāng)前線程不會馬上釋放該對象鎖,呈wait狀態(tài)的線程也不能馬上獲得該對象鎖,需要等notify()方法的線程將程序執(zhí)行完,也就是退出synchronized代碼塊后,當(dāng)前線程才會釋放鎖,而呈wait狀態(tài)所在的線程才可以獲取該對象鎖。當(dāng)?shù)谝粋€獲得對象鎖的wait線程運行完畢后,它會釋放掉該對象鎖,此時如果該對象沒有再次使用notify()語句,即便該對象已經(jīng)空閑,其他wait狀態(tài)線程由于沒得到通知,還是會繼續(xù)阻塞在wait狀態(tài),直到該對象發(fā)出一個notify或notifyAll.

4、wait() 方法可以使調(diào)用該方法的線程釋放共享資源的鎖,然后從運行狀態(tài)退出,進入等待隊列,直到被再次喚醒。

5、notify() 方法可以隨機喚醒等待隊列中等待同一共享資源的“一個”線程并使該線程退出等待隊列,進入可運行狀態(tài)。

6、notifyAll() 方法可以使所有正在等待隊列中等待同一共享資源的 全部 線程從等待狀態(tài)退出,進入可運行狀態(tài)。此時,優(yōu)先級最高的那個線程最先執(zhí)行,但也有可能是隨機執(zhí)行,取決JVM實現(xiàn)。

java并發(fā)的知識點有哪些 圖解:

1) 新建一個線程對象后,再調(diào)用它的start() 方法,系統(tǒng)會為此線程分配CPU資源,使其處于Runnable(可運行)狀態(tài),這是一個準備運行的階段。如果線程搶到CPU資源,線程就處于Running(運行)狀態(tài)。

2) Runnable狀態(tài)和Running狀態(tài)可相互切換,因為有可能線程運行一段時間后,有其它高優(yōu)先級的線程搶占CPU資源,這時此線程就從Running狀態(tài)變成Runable狀態(tài)。 線程進入Runnable狀態(tài)大體分為如下5種情況:(其實就是準備搶占CPU的狀態(tài)) 調(diào)用sleep()方法后經(jīng)過的時間超過了指定的休眠時間 線程調(diào)用的阻塞IO已經(jīng)返回,阻塞方法執(zhí)行完畢 線程成功的獲得了試圖同步的監(jiān)視器 線程正在等待某個通知,其他線程發(fā)出了通知 處于掛起狀態(tài)的線程調(diào)用了resume恢復(fù)方法

3) Blocked是阻塞的意思,例如遇到了一個IO操作,此時CPU處于空閑狀態(tài),可能會轉(zhuǎn)而把CPU時間片分配給其他線程,這時也可以稱為"暫停"狀態(tài)。Blocked狀態(tài)結(jié)束后,進入Runable狀態(tài),等待系統(tǒng)重新分配資源。 出現(xiàn)阻塞的情況大體分為如下5種: 線程調(diào)用sleep()方法,主動放棄占用的處理器資源 線程調(diào)用了阻塞式IO方法,在該方法返回前,該線程被阻塞 線程試圖獲得一個同步監(jiān)視器,但該同步監(jiān)視器正在被其他線程持有 線程在等待某個通知 線程調(diào)用了suspend()方法將該線程掛起。此方法容易導(dǎo)致死鎖,盡量避免使用

4) run()方法運行結(jié)束后進入銷毀階段,整個線程執(zhí)行完畢

7、每個鎖對象都有兩個隊列,一個是就緒隊列,一個是阻塞隊列。就緒隊列存儲了將要獲得鎖的線程,阻塞隊列存儲了被阻塞的線程。一個線程被喚醒后,才會進入就緒隊列(Runable狀態(tài)),等待CPU調(diào)度;反之,一個線程被wait()后,就會進入阻塞隊列,等待下一次被喚醒。

8、當(dāng)線程呈wait狀態(tài)時,調(diào)用線程對象的interrupt()方法會出現(xiàn)InterruptedException異常。

9、帶一個參數(shù)的wait(long)方法的功能是等待某一時間是否有線程對其進行喚醒,如果超過這個時間則自動喚醒。

10、管道流(pipeStream)是一種特殊的流,用于在不同線程間直接傳送數(shù)據(jù)。一個線程發(fā)送數(shù)據(jù)到輸出管道,另一個線程從輸入管道中讀取數(shù)據(jù)。通過使用管道,實現(xiàn)不同線程間的通信,而無需借助臨時文件之類的。

11、JDK 提供4個類來使線程間通信 1) PipedInputStream 和 PipedOutputStream 2 ) PipeReader 和 PipedWriter

12、使用代碼 inputStream.connect(outputStream) 或 outputStream.connect(inputStream) 的作用使兩個Stream之間產(chǎn)生通信鏈接,這樣才可以進行數(shù)據(jù)傳輸。

13、方法join() 的主要作用是等待線程對象銷毀。

14、方法join()的作用是使所屬的線程對象X正常執(zhí)行run()方法中的任務(wù),而使其當(dāng)前線程Z進行無限期的阻塞,等待線程X銷毀后再繼續(xù)執(zhí)行線程Z后邊的代碼。

15、方法join()具有使線程排隊運行的作用,有些類似同步的運行效果。join和synchronized的區(qū)別是:join在內(nèi)部使用的是wait()方法進行等待,而synchronized關(guān)鍵字使用的是 對象監(jiān)視器 原理做同步。

16、join() 與interrupt()遇到會出現(xiàn)異常。

17、類ThreadLocal 主要解決的就是每個線程綁定自己的值,可以將ThreadLocal類比喻成全局存放數(shù)據(jù)的盒子,盒子中可以存儲每個線程的私有數(shù)據(jù)。

18、第一次調(diào)用ThreadLocal 的get()方法返回值為null。如不想默認值返回為null,可以集成ThreadLocal 重寫 initialValue()方法。

19、InheritableThreadLocal 可以在子線程中取得父線程繼承下來的值。如果在子線程取得值的同時,主線程將值進行更改,那么子線程取到的還是舊值。

感謝各位的閱讀,以上就是“java并發(fā)的知識點有哪些”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對java并發(fā)的知識點有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI