老熟女激烈的高潮_日韩一级黄色录像_亚洲1区2区3区视频_精品少妇一区二区三区在线播放_国产欧美日产久久_午夜福利精品导航凹凸

重慶分公司,新征程啟航

為企業(yè)提供網(wǎng)站建設(shè)、域名注冊(cè)、服務(wù)器等服務(wù)

Java線程面試題有哪些

本篇內(nèi)容主要講解“Java線程面試題有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Java線程面試題有哪些”吧!

成都創(chuàng)新互聯(lián)公司專注于新區(qū)企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè),商城網(wǎng)站建設(shè)。新區(qū)網(wǎng)站建設(shè)公司,為新區(qū)等地區(qū)提供建站服務(wù)。全流程定制制作,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,成都創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務(wù)

Java 關(guān)鍵字volatile 與 synchronized 作用與區(qū)別?

JVM中存在一個(gè)主存區(qū)(Main Memory或Java Heap Memory),Java中所有變量都是存在主存中的,對(duì)于所有線程進(jìn)行共享,

而每個(gè)線程又存在自己的工作內(nèi)存(Working Memory),工作內(nèi)存中保存的是主存中某些變量的拷貝,

線程對(duì)所有變量的操作并非發(fā)生在主存區(qū),

而是發(fā)生在工作內(nèi)存中,而線程之間是不能直接相互訪問,變量在程序中的傳遞,是依賴主存來完成的。

在java中可以實(shí)現(xiàn)可見性的兩個(gè)關(guān)鍵字 

 1)使用關(guān)鍵字synchronized

 2)使用關(guān)鍵字volatile

 Synchronized能夠?qū)崿F(xiàn)多線程的原子性(同步)和可見性。

JVM關(guān)于Synchronized的兩條規(guī)定:

1)線程解鎖前,必須把共享變量的最新值刷新到主內(nèi)存中。

2)線程加鎖時(shí),將清空工作內(nèi)存中共享變量的值,從而使用共享變量時(shí)需要從主內(nèi)存中重新讀取最新的值(注意:加鎖和解鎖需要同一把鎖)。

volatile可以保證變量的可見性,但是不能保證復(fù)合操作的原子性

volatile如何實(shí)現(xiàn)內(nèi)存可見性?

深入來說:通過加入內(nèi)存屏障和禁止重排序優(yōu)化來實(shí)現(xiàn)的。

1)對(duì)volatile變量執(zhí)行寫操作時(shí),會(huì)在寫操作后加入一條store屏障指令。

2)對(duì)volatile變量執(zhí)行讀操作時(shí),會(huì)在讀操作后加入一條load屏障指令。

通俗地講:volatile變量在每次被線程訪問時(shí),都強(qiáng)迫從主內(nèi)存中重讀該變量的值,而當(dāng)該變量發(fā)生變化時(shí),又會(huì)強(qiáng)迫線程將最新的值刷新到主內(nèi)存,這樣任何時(shí)刻,不同的線程總能看到該變量的最新值。

線程寫volatile變量的過程:

1)改變線程工作內(nèi)存中volatile變量副本的值。

2)將改變后的副本的值從工作內(nèi)存刷新到主內(nèi)存。

線程讀volatile變量的過程:

1)從主內(nèi)存中讀取volatile變量的最新值到線程的工作內(nèi)存中。

2)從工作內(nèi)存中讀取volatile變量的副本

volatile不能保證volatile變量復(fù)合操作的原子性

對(duì)于下面的一段程序的使用volatile和synchronized

private int number = 0;              

number++;//不是原子操作                   

1讀取number的值                      

2將number的值加1                    

3寫入最新的number的值  

//加入synchronized,變?yōu)樵硬僮?nbsp;  

synchronized(thhis){ 

        number++; 

}

//變?yōu)関olatile變量,無法保證原子性

private volatile int number = 0;

volatile變量可用于提供線程安全,但是只能應(yīng)用于非常有限的一組用例:多個(gè)變量之間或者某個(gè)變量的當(dāng)前值與修改后值之間沒有約束。因此,單獨(dú)使用 volatile 還不足以實(shí)現(xiàn)計(jì)數(shù)器、互斥鎖或任何具有與多個(gè)變量相關(guān)的不變式(Invariants)的類(例如 “start <=end”)。

出于簡(jiǎn)易性或可伸縮性的考慮,您可能傾向于使用 volatile 變量而不是鎖。當(dāng)使用 volatile 變量而非鎖時(shí),某些習(xí)慣用法(idiom)更加易于編碼和閱讀。此外,volatile 變量不會(huì)像鎖那樣造成線程阻塞,因此也很少造成可伸縮性問題。在某些情況下,如果讀操作遠(yuǎn)遠(yuǎn)大于寫操作,volatile 變量還可以提供優(yōu)于鎖的性能優(yōu)勢(shì)。

volatile適合的使用場(chǎng)景

只能在有限的一些情形下使用 volatile 變量替代鎖。要使 volatile 變量提供理想的線程安全,必須同時(shí)滿足下面兩個(gè)條件:

(1)對(duì)變量的寫入操作不依賴其當(dāng)前值

(2)該變量沒有包含在具有其他變量的不變式中。

第一個(gè)條件的限制使 volatile 變量不能用作線程安全計(jì)數(shù)器。雖然增量操作(x++)看上去類似一個(gè)單獨(dú)操作,實(shí)際上它是一個(gè)由(讀取-修改-寫入)操作序列組成的組合操作,必須以原子方式執(zhí)行,而 volatile 不能提供必須的原子特性。實(shí)現(xiàn)正確的操作需要使x 的值在操作期間保持不變,而 volatile 變量無法實(shí)現(xiàn)這點(diǎn)。(然而,如果只從單個(gè)線程寫入,那么可以忽略第一個(gè)條件。)

總結(jié):

1)volatile比synchronized更輕量級(jí)。

2)volatile沒有synchronized使用的廣泛。

3)volatile不需要加鎖,比synchronized更輕量級(jí),不會(huì)阻塞線程。

4)從內(nèi)存可見性角度看,volatile讀相當(dāng)于加鎖,volatile寫相當(dāng)于解鎖。

5)synchronized既能保證可見性,又能保證原子性,而volatile只能保證可見性,無法保證原子性。

6)volatile本身不保證獲取和設(shè)置操作的原子性,僅僅保持修改的可見性。但是java的內(nèi)存模型保證聲明為volatile的long和double變量的get和set操作是原子的。

注意:

對(duì)64位(long、double)變量的讀寫可能不是原子操作

Java內(nèi)存模型允許JVM將沒有被volatile修飾的64位數(shù)據(jù)類型的讀寫操作劃分為兩次32位的讀寫操作來運(yùn)行。

導(dǎo)致問題:有可能會(huì)出現(xiàn)讀取到半個(gè)變量的情況。

解決方法:加volatile關(guān)鍵字。

一個(gè)問題:即使沒有保證可見性的措施,很多時(shí)候共享變量依然能夠在主內(nèi)存和工作內(nèi)存間得到及時(shí)的更新?

        答:一般只有在短時(shí)間內(nèi)高并發(fā)的情況下才會(huì)出現(xiàn)變量得不到及時(shí)更新的情況,因?yàn)镃PU在執(zhí)行時(shí)會(huì)很快地刷新緩存,

所以一般情況下很難看到這種問題。慢了不就不會(huì)刷新了。CPU運(yùn)算快的話,在分配的時(shí)間片內(nèi)就能完成所有工作:

工作內(nèi)從1->主內(nèi)存->工作內(nèi)存2,

這樣一來就保證了數(shù)據(jù)的可見性。在這個(gè)過程中,假如線程沒有在規(guī)定時(shí)間內(nèi)完成工作,然后這個(gè)線程就釋放CPU,分配給其它線程,

該線程就需要等待CPU下次給該線程分配時(shí)間片,如果在這段時(shí)間內(nèi)有別的線程訪問共享變量,可見性就沒法保證了。

什么是ThreadLocal變量?

ThreadLocal使用場(chǎng)合主要解決多線程中數(shù)據(jù)數(shù)據(jù)因并發(fā)產(chǎn)生不一致問題。

ThreadLocal為每個(gè)線程的中并發(fā)訪問的數(shù)據(jù)提供一個(gè)副本,通過訪問副本來運(yùn)行業(yè)務(wù),

這樣的結(jié)果是耗費(fèi)了內(nèi)存,單大大減少了線程同步所帶來性能消耗,也減少了線程并發(fā)控制的復(fù)雜度。

Spring使用ThreadLocal解決線程安全問題。通常只有無狀態(tài)的Bean才可以在多線程環(huán)境下共享,

在Spring中,絕大部分Bean都可以聲明為singleton作用域。就是因?yàn)镾pring對(duì)一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非線程安全的“狀態(tài)性對(duì)象”采用ThreadLocal進(jìn)行封裝,

讓它們也成為線程安全的“狀態(tài)性對(duì)象”,

因此有狀態(tài)的Bean就能夠以singleton的方式在多線程中正常工作了。

一般的Web應(yīng)用劃分為控制層、服務(wù)層和持久層三個(gè)層次,在不同的層中編寫對(duì)應(yīng)的邏輯

,下層通過接口向上層開放功能調(diào)用。在一般情況下,從接收請(qǐng)求到返回響應(yīng)所經(jīng)過的所有程序調(diào)用都同屬于一個(gè)線程。

這樣用戶就可以根據(jù)需要,將一些非線程安全的變量以ThreadLocal存放,

在同一次請(qǐng)求響應(yīng)的調(diào)用線程中,

所有對(duì)象所訪問的同一ThreadLocal變量都是當(dāng)前線程所綁定的。

Thread類有一個(gè)類型為ThreadLocal.ThreadLocalMap的實(shí)例變量threadLocals,也就是說每個(gè)線程有一個(gè)自己的ThreadLocalMap。

ThreadLocalMap有自己的獨(dú)立實(shí)現(xiàn),可以簡(jiǎn)單地將它的key視作ThreadLocal,value為代碼中放入的值(實(shí)際上key并不是ThreadLocal本身,而是它的一個(gè)弱引用)。

每個(gè)線程在往ThreadLocal里放值的時(shí)候,都會(huì)往自己的ThreadLocalMap里存,讀也是以ThreadLocal作為引用,在自己的map里找對(duì)應(yīng)的key,從而實(shí)現(xiàn)了線程隔離。

ThreadLocalMap有點(diǎn)類似HashMap的結(jié)構(gòu),只是HashMap是由數(shù)組+鏈表實(shí)現(xiàn)的,而ThreadLocalMap中并沒有鏈表結(jié)構(gòu)。

我們還要注意Entry, 它的key是ThreadLocal k ,繼承自WeakReference, 也就是我們常說的弱引用類型。.

為了搞清楚這個(gè)問題,我們需要搞清楚Java的四種引用類型:

強(qiáng)引用:我們常常new出來的對(duì)象就是強(qiáng)引用類型,只要強(qiáng)引用存在,垃圾回收器將永遠(yuǎn)不會(huì)回收被引用的對(duì)象,哪怕內(nèi)存不足的時(shí)候

軟引用:使用SoftReference修飾的對(duì)象被稱為軟引用,軟引用指向的對(duì)象在內(nèi)存要溢出的時(shí)候被回收

弱引用:使用WeakReference修飾的對(duì)象被稱為弱引用,只要發(fā)生垃圾回收,若這個(gè)對(duì)象只被弱引用指向,那么就會(huì)被回收

虛引用:虛引用是最弱的引用,在 Java 中使用 PhantomReference 進(jìn)行定義。虛引用中唯一的作用就是用隊(duì)列接收對(duì)象即將死亡的通知.

這個(gè)問題剛開始看,如果沒有過多思考,弱引用,還有垃圾回收,那么肯定會(huì)覺得是null。

其實(shí)是不對(duì)的,因?yàn)轭}目說的是在做 threadlocal.get() 操作,證明其實(shí)還是有強(qiáng)引用存在的,所以 key 并不為 null,如下圖所示,ThreadLocal的強(qiáng)引用仍然是存在的

如果我們的強(qiáng)引用不存在的話,那么 key 就會(huì)被回收,也就是會(huì)出現(xiàn)我們 value 沒被回收,key 被回收,導(dǎo)致 value 永遠(yuǎn)存在,出現(xiàn)內(nèi)存泄漏。

HashMap中解決沖突的方法是在數(shù)組上構(gòu)造一個(gè)鏈表結(jié)構(gòu),沖突的數(shù)據(jù)掛載到鏈表上,如果鏈表長(zhǎng)度超過一定數(shù)量則會(huì)轉(zhuǎn)化成紅黑樹。

而ThreadLocalMap中并沒有鏈表結(jié)構(gòu),所以這里不能適用HashMap解決沖突的方式了。

如果我們插入一個(gè)value=27的數(shù)據(jù),通過hash計(jì)算后應(yīng)該落入第4個(gè)槽位中,而槽位4已經(jīng)有了Entry數(shù)據(jù)。

此時(shí)就會(huì)線性向后查找,一直找到Entry為null的槽位才會(huì)停止查找,將當(dāng)前元素放入此槽位中。當(dāng)然迭代過程中還有其他的情況,比如遇到了Entry不為null且key值相等的情況,還有Entry中的key值為null的情況等等都會(huì)有不同的處理,后面會(huì)一一詳細(xì)講解。

這里還畫了一個(gè)Entry中的key為null的數(shù)據(jù)(Entry=2的灰色塊數(shù)據(jù)),因?yàn)閗ey值是弱引用類型,所以會(huì)有這種數(shù)據(jù)存在。在set過程中,如果遇到了key過期的Entry數(shù)據(jù),實(shí)際上是會(huì)進(jìn)行一輪探測(cè)式清理操作的,具體操作方式后面會(huì)講到

 實(shí)際的通過ThreadLocal創(chuàng)建的副本是存儲(chǔ)在每個(gè)線程自己的threadLocals中的;

為何threadLocals的類型ThreadLocalMap的鍵值為ThreadLocal對(duì)象,因?yàn)槊總€(gè)線程中可有多個(gè)threadLocal變量,就像上面代碼中的longLocal和stringLocal;

ThreadLocal和Synchonized都用于解決多線程并發(fā)訪問。但是ThreadLocal與synchronized有本質(zhì)的區(qū)別。synchronized是利用鎖的機(jī)制,

使變量或代碼塊在某一時(shí)該只能被一個(gè)線程訪問。而ThreadLocal為每一個(gè)線程都提供了變量的副本,

使得每個(gè)線程在某一時(shí)間訪問到的并不是同一個(gè)對(duì)象,這樣就隔離了多個(gè)線程對(duì)數(shù)據(jù)的數(shù)據(jù)共享。而Synchronized卻正好相反,它用于在多個(gè)線程間通信時(shí)能夠獲得數(shù)據(jù)共享

如何在Java中實(shí)現(xiàn)線程?

在語言層面有三種方式。java.lang.Thread 類的實(shí)例就是一個(gè)線程但是它需要調(diào)用java.lang.Runnable接口來執(zhí)行,

由于線程類本身就是調(diào)用的Runnable接口所以你可以繼承 java.lang.Thread 類或者直接調(diào)用Runnable接口來重寫run()方法實(shí)現(xiàn)線程。

第三種 實(shí)現(xiàn)Callable<>接口并重寫call方法

Java中Runnable和Callable有什么不同?

Runnable和Callable都代表那些要在不同的線程中執(zhí)行的任務(wù)。

Runnable從JDK1.0開始就有了,Callable是在 JDK1.5增加的。

它們的主要區(qū)別是Callable的 call() 方法可以返回值和拋出異常,而Runnable的run()方法沒有這些功能。

Callable可以返回裝載有計(jì)算結(jié)果的Future對(duì)象

什么是線程安全?Vector是一個(gè)線程安全類嗎?

如果你的代碼所在的進(jìn)程中有多個(gè)線程在同時(shí)運(yùn)行,而這些線程可能會(huì)同時(shí)運(yùn)行這段代碼。如果每次運(yùn)行結(jié)果和單線程運(yùn)行的結(jié)果是一樣的,

而且其他的變量 的值也和預(yù)期的是一樣的,就是線程安全的。一個(gè)線程安全的計(jì)數(shù)器類的同一個(gè)實(shí)例對(duì)象在被多個(gè)線程使用的情況下也不會(huì)出現(xiàn)計(jì)算失誤。

很顯然你可以將集合類分 成兩組,線程安全和非線程安全的。Vector 是用同步方法來實(shí)現(xiàn)線程安全的, 而和它相似的ArrayList不是線程安全的。

Java中notify 和 notifyAll有什么區(qū)別?

這又是一個(gè)刁鉆的問題,因?yàn)槎嗑€程可以等待單監(jiān)控鎖,Java API 的設(shè)計(jì)人員提供了一些方法當(dāng)?shù)却龡l件改變的時(shí)候通知它們,但是這些方法沒有完全實(shí)現(xiàn)。

notify()方法不能喚醒某個(gè)具體的線程,所以只有一個(gè)線程在等 待的時(shí)候它才有用武之地。

而notifyAll()喚醒所有線程并允許他們爭(zhēng)奪鎖確保了至少有一個(gè)線程能繼續(xù)運(yùn)行。

為什么wait, notify 和 notifyAll這些方法不在thread類里面?

這是個(gè)設(shè)計(jì)相關(guān)的問題,它考察的是面試者對(duì)現(xiàn)有系統(tǒng)和一些普遍存在但看起來不合理的事物的看法。回答這些問題的時(shí)候,

你要說明為什么把這些方法放在 Object類里是有意義的,還有不把它放在Thread類里的原因。一個(gè)很明顯的原因是JAVA提供的鎖是對(duì)象級(jí)的而不是線程級(jí)的,

每個(gè)對(duì)象都有鎖,通 過線程獲得。如果線程需要等待某些鎖那么調(diào)用對(duì)象中的wait()方法就有意義了。

如果wait()方法定義在Thread類中,線程正在等待的是哪個(gè)鎖 就不明顯了。簡(jiǎn)單的說,

由于wait,notify和notifyAll都是鎖級(jí)別的操作,所以把他們定義在Object類中因?yàn)殒i屬于對(duì)象。

什么是FutureTask?

在Java并發(fā)程序中FutureTask表示一個(gè)可以取消的異步運(yùn)算。它有啟動(dòng)和取消運(yùn)算、查詢運(yùn)算是否完成和取回運(yùn)算結(jié)果等方法。

只有當(dāng)運(yùn)算完 成的時(shí)候結(jié)果才能取回,如果運(yùn)算尚未完成get方法將會(huì)阻塞。一個(gè)FutureTask對(duì)象可以對(duì)調(diào)用了Callable和Runnable的對(duì)象進(jìn)行包 裝,

由于FutureTask也是調(diào)用了Runnable接口所以它可以提交給Executor來執(zhí)行。

有哪些不同的線程生命周期?

        當(dāng)我們?cè)贘ava程序中新建一個(gè)線程時(shí),它的狀態(tài)是New。當(dāng)我們調(diào)用線程的start()方法時(shí),

狀態(tài)被改變?yōu)镽unnable。線程調(diào)度器會(huì)為Runnable線程池中的線程分配CPU時(shí)間并且講它們的狀態(tài)改變?yōu)镽unning。

什么是死鎖(Deadlock)?如何分析和避免死鎖?

        死鎖是指兩個(gè)以上的線程永遠(yuǎn)阻塞的情況,這種情況產(chǎn)生至少需要兩個(gè)以上的線程和兩個(gè)以上的資源。

        分析死鎖,我們需要查看Java應(yīng)用程序的線程轉(zhuǎn)儲(chǔ)。我們需要找出那些狀態(tài)為BLOCKED的線程和他們等待的資源。每個(gè)資源都有一個(gè)唯一的id,用這個(gè)id我們可以找出哪些線程已經(jīng)擁有了它的對(duì)象鎖。

        避免嵌套鎖,只在需要的地方使用鎖和避免無限期等待是避免死鎖的通常辦法其他的線程狀態(tài)還有Waiting,Blocked 和Dead。

到此,相信大家對(duì)“Java線程面試題有哪些”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!


網(wǎng)站欄目:Java線程面試題有哪些
URL標(biāo)題:http://www.xueling.net.cn/article/gpsjds.html

其他資訊

在線咨詢
服務(wù)熱線
服務(wù)熱線:028-86922220
TOP
主站蜘蛛池模板: 伊人久色 | 日日夜夜天天操 | 亚洲精品一区二区三区精品 | 99久久精品国产国产毛片 | 久久久久久久久久久影院 | 亚洲av乱码一区二区三区 | 国产精品99久久精品爆乳 | 免费乱人伦 | 成人欧美一区二区三区色青冈 | av中文字幕无码免费看 | 一二三四社区在线视频观看 | 亚洲美女牲交高清淅视频 | 国产精品久久久久久久久免费看 | 日韩精品亚洲精品第一页 | 日韩理论片中文字幕 | 明星angelababy造梦视频 | 大胆日本无码一区二区 | 欧洲精品乱码久久久久久 | 亚洲AV日韩AV永久无码色欲 | 国产成人?合一区二区三区 国产人成一区二区三区影院 | 欧美黄色网络 | 亚洲国产成人久久精品软件 | 国产精品久久久久久久久久久杏吧 | 毛豆日产精品卡2卡3卡4卡免费 | 一区二区在线观看免费 | 久久国产欧美一区二区精品爱欲 | 亚洲精品视频专区 | 欧美一区二区三区四区视频 | gogo全球大胆高清人露出91 | 超清AV在线播放不卡无码 | 在线天堂资源WWW在线污 | 熟妇高潮一区二区三区 | 中文字幕色欲AV亚洲二区 | 性一乱一搞一交一伦一性 | 四虎成人精品国产永久免费 | 永久免费无码网站在线观看 | 亚洲国产精品隔壁老王 | 性欧美videos喷潮 | 无码专区3D动漫精品免费 | 息与子五十路中文字幕 | 男人肌肌捅女人肌肌视频 |