最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

過關(guān)斬將之路-線程基礎(chǔ)&Volatile(IT楓斗者)

2023-04-17 11:11 作者:IT楓斗者-跳蚤網(wǎng)  | 我要投稿

線程基礎(chǔ)

1問:線程的狀態(tài)是怎樣的?

1答

2問:多線程一定比單線程快嗎?

2答:不一定,因?yàn)榫€程切換是有開銷的,需要消耗性能。若CPU是單核,那你開多個線程可能會使程序變慢,而單線程則會很快。


3問:多線程的優(yōu)缺點(diǎn)有哪些?

3答

優(yōu)點(diǎn)

  • 資源利用率更好

比如:下載文件。我們的流程是這樣的:

  1. 將下載任務(wù)放到隊列。

  2. 從隊列里取出下載鏈接去下載。

若是單線程的話,那費(fèi)老勁了,一個一個的下載,CPU大部分時間是空閑的,若是多線程呢?同時下載一批任務(wù),豈不是更爽快?CPU忙起來吧!

  • 提高系統(tǒng)的吞吐率

多線程編程使得一個進(jìn)程中可以有多個并發(fā)(即同時進(jìn)行)的操作。例如,當(dāng)一個線程因?yàn)镮/O操作而處于等待時,其他線程然可以執(zhí)行其操作。

  • 響應(yīng)速度快

還以下載文件的案例,若我們請求一個下載接口,要等下載完才返回成功,那豈不是需要等太久了,如果我們業(yè)務(wù)邏輯都沒問題直接返回成功豈不是更好?然后下載任務(wù)交由其他線程去處理。

缺點(diǎn)

  • 線程切換是有開銷的,這會在一定情況下導(dǎo)致程序運(yùn)行變慢。

  • 多線程程序必須非常小心地同步代碼,否則會引起死鎖或數(shù)據(jù)不準(zhǔn)確。

  • 多線程程序極難調(diào)試,并且一些bug非常隱蔽,可能你99次都是對的,但是有1次是錯的,不像單線程程序那么容易暴露問題。

4問:線程和進(jìn)程的區(qū)別?

4答

  • 進(jìn)程是資源分配的基本單位。

  • 線程是處理器(CPU)調(diào)度的基本單位。

  • 進(jìn)程是操作系統(tǒng)級別的,線程是進(jìn)程級別的。

  • 一個進(jìn)程包含多個線程。(我們可以打開一個IDEA/Eclipse,然后JConsole去看線程數(shù),會發(fā)現(xiàn)一IDEA/Eclipse進(jìn)程啟動了N多個線程。

5問:用Runnable還是Thread?

5答

這個問題很容易回答,如果你知道Java不支持類的多重繼承,但允許你實(shí)現(xiàn)多個接口。所以如果你要繼承其他類,當(dāng)然是調(diào)用Runnable接口好了。也是大家一直所說的:面向接口編程。


6答:Thread 類中的start()和 run()方法有什么區(qū)別?

6答:真正啟動線程的是start()方法而不是run(),run()和普通的成員方法一樣,可以重復(fù)使用,但不能啟動一個新線程。start()方法才會啟動新線程。


7問:sleep()和wait()的區(qū)別?

7答

  • sleep為Thread的方法,而wait為Object的方法。

  • 最大本質(zhì)的區(qū)別是:sleep不釋放鎖,wait釋放鎖。

  • 用法上的不同:sleep(milliseconds)可以用時間指定來使他自動醒過來,如果時間不到你只能調(diào)用interreput()來終止線程;wait()可以用notify()/notifyAll()直接喚起。

  • wait在使用前必須要獲取鎖(synchronized塊包起來),而sleep可以在任何地方使用。

8問:阻塞與等待的區(qū)別?

8答

阻塞:當(dāng)一個線程試圖獲取對象鎖(非java.util.concurrent庫中的鎖,即synchronized),而該鎖被其他線程持有,則該線程進(jìn)入阻塞狀態(tài)。它的特點(diǎn)是使用簡單,由JVM調(diào)度器來決定喚醒自己,而不需要由另一個線程來喚醒自己,不響應(yīng)中斷。

等待:當(dāng)一個線程等待另一個線程通知調(diào)度器一個條件時,該線程進(jìn)入等待狀態(tài)。它的特點(diǎn)是需要等待另一個線程顯式地喚醒自己,實(shí)現(xiàn)靈活,語義更豐富,可響應(yīng)中斷。例如調(diào)用:Object.wait()、Thread.join()以及等待Lock或Condition。


9問:創(chuàng)建線程的方式有哪些?

9答

  • 繼承Thread類

  • 實(shí)現(xiàn)Runnable接口

  • 匿名內(nèi)部類(直接Thread/實(shí)現(xiàn)Runnable接口 )

  • 帶返回值的方式(FutureTask)

  • 線程池的方式

10問:為什么wait和notify方法要在同步塊中調(diào)用?

10答:因?yàn)橹挥凶哌M(jìn)同步塊,才說明該線程有對資源的持有權(quán),而只要對資源有持有權(quán),才有資格去進(jìn)行釋放鎖和通知其他沒有獲取到鎖的線程。否則就無法保證代碼的原子性。


11問:什么是同步鎖和死鎖?

11答

  • 同步鎖

當(dāng)多個線程同時訪問同一個數(shù)據(jù)時,很容易出現(xiàn)問題。為了避免這種情況出現(xiàn),我們要保證線程同步互斥,就是指并發(fā)執(zhí)行的多個線程,在同一時間內(nèi)只允許一個線程訪問共享數(shù)據(jù)。?Java?中可以使用?synchronized?關(guān)鍵字來取得一個對象的同步鎖。

  • 死鎖

何為死鎖,就是多個線程同時被阻塞,它們中的一個或者全部都在等待某個資源被釋放。


Volatile

12問:簡單聊聊volatile?

12答

被volatile修飾的共享變量,就具有了以下兩點(diǎn)特性:

  • 保證了多線程對該變量操作的內(nèi)存可見性

  • 禁止指令重排序

但是并不保證原子性。


13問:什么是可見性?

13答:每個線程都有獨(dú)立的工作內(nèi)存,所以線程對變量進(jìn)行修改的時候會先將值修改到工作內(nèi)存,其他線程是不可見的,可見性是指當(dāng)一個線程修改了共享變量的值,其他線程能夠立即得知這個修改。加上volatile可以保證可見性,volatile變量保證修改的新值能夠立馬同步到主存,其他線程使用時也會感知到這個共享變量已經(jīng)有新值了,讓自己的工作內(nèi)存值失效,立即從主存重新獲取 ,這就保證了多線程操作時變量的可見性。


14問:指令重排是什么意思?

14答

JVM會對編譯后的class進(jìn)行優(yōu)化,重排序也是JVM優(yōu)化的手段之一,也就是A、B兩行代碼的順序編譯后可能變成B、A,這就是重新排序了。有時候可能會造成一些問題,比如狀態(tài)標(biāo)記量、雙重檢查鎖的單例寫法。

比如雙重檢查鎖的單例(這個解決方案需要JDK5或更高版本):

若不加volatile的話這就是一個線程不安全的單例寫法。在線程執(zhí)行到第1處,代碼讀取到instance不為null時,instance引用的對象有可能發(fā)生了指令重排給分配了內(nèi)存空間,但是還沒有完成初始化!所以業(yè)務(wù)系統(tǒng)獲取到的instance實(shí)例可能是null

問題的根源如下:

前面的雙重檢查鎖定實(shí)例代碼的第4處 instance = new Instance(); 創(chuàng)建了一個對象。這一行代碼可以分解為如下的3行偽代碼。

上面3行偽代碼中的2和3之間可能會被重排序,2和3之間重排序之后的執(zhí)行時序如下:

15問:volatile怎么保證原子性的?

15答:這是個坑,因?yàn)関olatile無法保證原子性。

16問:volatile和synchronized有啥區(qū)別?

16答

  • volatile僅僅作用在變量上,synchronized可以作用在變量上也可以方法上,還支持代碼塊。

  • volatile能保證可見性和防止重排序,不能保證原子性。synchronized能保證原子性和可見性和防止指令重排序。

  • volatile不會造成線程阻塞,synchronized會造成線程阻塞。

  • 其實(shí)全是圍繞這句話來說的:volatile不是鎖,synchronized是把可重入排他鎖。

17問:volatile用在什么地方?

17答

  • 線程安全的單例:雙重鎖檢查無法保證線程安全性,需要volatile防止重排序來保證。

  • 狀態(tài)標(biāo)記量:一個狀共享態(tài)變量需要多個線程讀寫的時候,可以用volatile保證可見性。

18問:volatile是如何保證可見性和指令重排的(它的實(shí)現(xiàn)原理)?

18答

加入volatile關(guān)鍵字時,會多出一個lock前綴指令,lock前綴指令實(shí)際上相當(dāng)于一個內(nèi)存屏障,這個內(nèi)存屏障包含如下三個功能:

  • 它確保指令重排序時不會把其后面的指令排到內(nèi)存屏障之前的位置,也不會把前面的指令排到內(nèi)存屏障的后面;即在執(zhí)行到內(nèi)存屏障這句指令時,在它前面的操作已經(jīng)全部完成。

  • 它會強(qiáng)制將對緩存的修改操作立即寫入主存。

  • 如果是寫操作,它會導(dǎo)致其他CPU中對應(yīng)的緩存行失效。


過關(guān)斬將之路-線程基礎(chǔ)&Volatile(IT楓斗者)的評論 (共 條)

分享到微博請遵守國家法律
璧山县| 清水河县| 长岛县| 交口县| 三明市| 军事| 朝阳市| 吉首市| 特克斯县| 紫阳县| 兴城市| 元谋县| 瑞昌市| 吴江市| 山西省| 烟台市| 东至县| 乌兰察布市| 拜泉县| 平遥县| 松阳县| 军事| 长武县| 正定县| 衡阳市| 万源市| 马尔康县| 中宁县| 逊克县| 利辛县| 郎溪县| 仙居县| 肇东市| 阿克陶县| 蕉岭县| 图们市| 通榆县| 昌平区| 修武县| 桐庐县| 晋城|