這篇文章是研一剛入學時寫的,今天整理草稿時才被我挖出來。當時混混沌沌的面試,記下來了一些併發的面試問題,不少尚未回答。到如今也學習了很多併發的知識,回過頭來看這些問題和當時整理的答案,漏洞百出又十分好笑。發表出來權當對本身的一個提醒——若是不能一直進步,你就看不到當初傻逼的本身。 java
曾經,我在面試Java研發實習生時最常聽到的一句話就是:git
搞Java怎麼能不學併發呢?程序員
沒錯,真的是通過了面試官的無數鄙視,我才知道Java併發編程在Java語言中的重要性。github
悲觀鎖假設最壞的狀況(若是你不鎖門,那麼搗蛋鬼就會闖入並搞得一團糟),而且只有在確保其餘線程不會干擾(經過獲取正確的鎖)的狀況下才能執行下去。面試
常見實現如獨佔鎖等。算法
安全性更高,但在中低併發程度下的效率更低。編程
樂觀鎖藉助衝突檢查機制來判斷在更新過程當中是否存在其餘線程的干擾,若是存在,這個操做將失敗,而且能夠重試(也能夠不重試)。安全
常見實現如CAS等。併發
部分樂觀鎖削弱了一致性,但中低併發程度下的效率大大提升。函數
從面相接口的角度上講,實際上只有一種方法實現Runable接口;但Thread類爲線程操做提供了更多的支持,因此一般作法是實現Runable接口,實例化並傳入Thread類的構造函數。
經過synchronized關鍵字修飾每一個方法。
依據synchronized關鍵字引伸出如下問題。
持有鎖的對象不一樣:
從而致使兩者的意義不一樣:
ConcurrentHashMap的線程安全實現與HashTable不一樣:
要從最簡單的答起,業界最經常使用的是重點,有新意就放在最後。
List list = Collection.synchronizedList(new ArrayList())
。從而引伸出以下問題:
Exchanger、Callable&Future、阻塞隊列BlockingQueue的實現原理
算法核心可歸納爲兩步:
詳細待補充。
參考:
最大的不一樣是在等待時wait會釋放鎖,而sleep一直持有鎖。Wait一般被用於線程間交互,sleep一般被用於暫停執行。
主要緣由是JAVA提供的鎖是對象級的而不是線程級的,每一個對象都有鎖,經過線程得到。因爲wait,notify和notifyAll都是鎖級別的操做,因此把他們定義在Object類中由於鎖屬於對象。
Java API強制要求這樣作,若是你不這麼作,你的代碼會拋出IllegalMonitorStateException異常。還有一個緣由是爲了不wait和notify之間產生競態條件。
處於等待狀態的線程可能會收到錯誤警報和僞喚醒,若是不在循環中檢查等待條件,程序就會在沒有知足結束條件的狀況下退出。
兩個方法均可以向線程池提交任務,execute()方法的返回類型是void,它定義在Executor接口中, 而submit()方法能夠返回持有計算結果的Future對象,它定義在ExecutorService接口中,它擴展了Executor接口,其它線程池類像ThreadPoolExecutor和ScheduledThreadPoolExecutor都有這些方法。
Volatile變量能夠確保先行關係,即寫操做會發生在後續的讀操做以前, 但它並不能保證原子性。例如用volatile修飾count變量那麼 count++ 操做就不是原子性的。而AtomicInteger類提供的atomic方法可讓這種操做具備原子性如getAndIncrement()方法會原子性的進行增量操做把當前值加一,其它數據類型和引用變量也能夠進行類似操做。
Thread類的sleep()和yield()方法將在當前正在執行的線程上運行。因此在其餘處於等待狀態的線程上調用這些方法是沒有意義的。這就是爲何這些方法是靜態的。它們能夠在當前正在執行的線程中工做,並避免程序員錯誤的認爲能夠在其餘非運行線程調用這些方法。
本文連接:Java高併發綜合
做者:猴子007
出處:monkeysayhi.github.io
本文基於 知識共享署名-相同方式共享 4.0 國際許可協議發佈,歡迎轉載,演繹或用於商業目的,可是必須保留本文的署名及連接。