Java一些小知識整理,用於面試

weixin_34208283發表於2017-06-26
1.CloseGuard

CloseGuard原始碼
大多數出現該情況是記憶體洩漏,你佔用了資源沒有釋放或者關閉,比如資料庫。

 CloseGuard is a mechanism for flagging implicit finalizer cleanup of
 * resources that should have been cleaned up by explicit close
 * methods (aka "explicit termination methods" in Effective Java).
 * A simple example: <pre>   {@code
 *   class Foo {
 *
 *       private final CloseGuard guard = CloseGuard.get();
 *
 *       ...
 *
 *       public Foo() {
 *           ...;
 *           guard.open("cleanup");
 *       }
 *
 *       public void cleanup() {
 *          guard.close();
 *          ...;
 *       }
 *
 *       protected void finalize() throws Throwable {
 *           try {
 *               if (guard != null) {
 *                   guard.warnIfOpen();
 *               }
 *               cleanup();
 *           } finally {
 *               super.finalize();
 *           }
 *       }
 *   }
 * }

原始碼的列子很清楚,需要finalize配合使用,它能制定在你的Foo,回收必須強制呼叫cleanup回收,不然在物件析構的時候就報錯。具體錯誤官方有。

4037823-bdf11c93232a8d35.png
出自深入理解Android(卷2).鄧平凡.2012-363頁
2.序列化
4037823-4fdb5d8f19182716.png

4037823-2d43caad93f7663e.png
出自Effective Java 中文第二版
3.泛型
4037823-89a55ed0b7b8c001.png
出自Effective Java 中文第二版
4.同步,重入鎖,volatile

什麼叫鎖,計算機實現原理:
一般分為2類:
1.快取加鎖:就是如果快取在處理器快取行中記憶體區域在LOCK操作期間被鎖定,當它執行鎖操作回寫記憶體時,處理器不在匯流排上聲言LOCK#訊號,而是修改內部的記憶體地址,並允許它的快取一致性機制來保證操作的原子性,因為快取一致性機制會阻止同時修改被兩個以上處理器快取的記憶體區域資料,當其他處理器回寫已被鎖定的快取行的資料時會起快取行無效,在例1中,當CPU1修改快取行中的i時使用快取鎖定,那麼CPU2就不能同時快取了i的快取行。
2.匯流排加鎖:匯流排鎖就是使用處理器提供的一個LOCK#訊號,當一個處理器在匯流排上輸出此訊號時,其他處理器的請求將被阻塞住,那麼該處理器可以獨佔使用共享記憶體
併發原理

ConcurrentHashMap
4037823-c4c83e7d42bde7ed.png

4037823-782b6ab7b60e3310.png
出自Java併發程式設計實戰(中文版)5.2.1章
ConcurrentMap
4037823-8b7c46524c2e0f21.png
Paste_Image.png
CopyOnWriteArrayList
4037823-a8215e944dfa0dac.png
出自Java併發程式設計實戰(中文版)5.2.2章
BlockingQueue
4037823-af4a30da594de156.png
出自Java併發程式設計實戰(中文版)5.3章
BlockingDeque
4037823-268b553b0da02a51.png
出自Java併發程式設計實戰(中文版)5.3.3章
同步工具類
4037823-3d8982f66ded2287.png
出自Java併發程式設計實戰(中文版)5.5章
閉鎖

閉鎖是一次性物件的使用,一旦進入終止狀態,就不能被重置。


4037823-c406db636a129d2e.png

4037823-191163e021f5ad7c.png
出自Java併發程式設計實戰(中文版)5.5.1章

解釋下原理:
按前面紅框中游戲玩家舉例。我有5個玩家,進入我的主機,每個玩家是一個執行緒。
我作為主機控制著,我希望知道所有玩家作為準備後,需要多長時間,然後進行同步下一步任務。
這時候startGate會鎖住Thread中的Task,等你進來之後就開始countDown讓你準備。
最後endGate,正如文中所說,主機不會去關係某個人做完準備工作的時間,當5個人全部做完,那麼我主機就知道所有人總時間了。


4037823-ea8b999c788a007d.png
另一個閉鎖的使用例子
訊號量
4037823-5b526971818c7410.png

4037823-d4cee6fa206c872e.png
重入定義,出自Java併發程式設計實戰(中文版)5.5.4章
柵欄
4037823-f3b1e3e41f51fcf4.png

4037823-b5b9edc439a3d9b2.png

4037823-bad5f5d2e60f0297.png
重入定義,出自Java併發程式設計實戰(中文版)5.5章
重入
4037823-499816e13543d626.png
重入定義,出自Java併發程式設計實戰(中文版)2.3.2章
long和double的坑:
4037823-193bba429b3b7ddb.png
同步鎖的優化,分解鎖和分段鎖
4037823-b39ee58d27654bae.png

4037823-9af653a85f73efbf.png
分解鎖優化

4037823-11c8a56fe3e873c5.png

4037823-5b9949ebe3988c81.png
分段鎖
Condition
4037823-944ea3c7d1e5fd5f.png

4037823-82b91536caa1da39.png

4037823-998857920b3ffc79.png
出自Java併發程式設計實戰(中文版)14.3章

這裡解釋下lock.lock()用於同步使用了,也就相當於一個synchronizer,真正阻塞在await()。

4037823-129d9f9dee587c77.png

4037823-7c0aa9cb489ccabe.png

4037823-4cffd6a6522531b5.png

4037823-9068d78fc1084b27.png
4037823-76cc221dd0e9940f.png
出自Java併發程式設計實戰(中文版)4章

volatile原則就是:僅當一個變數參與到包含其他狀態變數的不變性條件時,才可以宣告volatile型別。也就是說這貨是個獨立的,不能帶節奏以後,其他變數值會被他影響。


4037823-705db3b7383138c4.png
併發的效率
下面看一個“錯誤”加鎖例子:
4037823-9b3fc588624a6899.png
出自Java併發程式設計實戰(中文版)4章
4.非同步
Future
4037823-c96cb677afb4fda9.png

4037823-d53ed2989bec6d2d.png
出自Java併發程式設計實戰(中文版)5.5.2章
Callable和Future
4037823-c0c1ed04ca9d245b.png

4037823-8543f1e68845f1e2.png
出自Java併發程式設計實戰(中文版)6.3.2章
ExecuteCompletionService
4037823-693e9c295618892e.png

4037823-20c5bf8644969eca.png
出自Java併發程式設計實戰(中文版)6.3.3章

這裡解釋下for迴圈中的take(),是從ExecuteCompletionService中BlockingQueue中拿出來的Future,本身不會阻塞。但Future拿結果get會阻塞,直到資料完成。

5.物件回收

C++是用引用計數器,Java是用GC Root

6.守護執行緒
4037823-4af6ca74916f0d51.png
出自Java併發程式設計實戰(中文版)7.4.2章
7.執行緒池使用
4037823-e2ef95ff173f4bbf.png

4037823-6948d6da4df1e8e3.png
一個自定義執行緒池執行器,注意策略使用

4037823-3d19ba43ac5af4d0.png
設定執行緒錯誤堆疊

4037823-80cbf286a8fabd58.png
一個訊號量使用(Semaphore),先條件大小阻塞,才有任務提交

注意學習上面Semaphore使用,一般可以配合ThreadLoacl使用。


4037823-d8341e88dd4d5952.png

4037823-10590f72558b408e.png
出自Java併發程式設計實戰(中文版)8.9章

注意學習上面ThreadLoacl使用,每個執行緒有自己例項空間堆疊,不受其他執行緒影響,不能線上程通訊使用。
8.顯示鎖
4037823-db2cf6fea836a551.png
出自Java併發程式設計實戰(中文版)13.1章

4037823-727e0309065bb569.png
就效能方面還是sychronized效率高,但伸縮性和擴充套件性沒有顯示鎖好用
9.顯示鎖讀寫鎖
4037823-a2cac68df4b2557a.png

4037823-652a92655d9f893a.png

4037823-a855014a65f97031.png

4037823-8b738e90424a482a.png

4037823-c8b7137019677d31.png
10非阻塞演算法
4037823-1e63baa34be5092f.png

4037823-a717f273a27c0a16.png

說明下:compareAndSet既能提供原子性,又能提供可見性。當一個執行緒需要修改棧狀態時,它能有寫入volaite型別一樣,快速同步記憶體效果。

相關文章