關於Java鎖細節的博客,蠻受讀者歡迎的。也有許多不足,好比排版,一些細節等。Java鎖細節與鎖之編程細節講述鎖的兩個不一樣方面,因此分開寫。Java鎖細節是講述每種鎖的細節,把鎖當作人的話,講述的是男人,女人,大人,小孩的細節。鎖之編程細節講述的如高性能的使用鎖。如同讓人怎麼跑得塊而已。java
編程細節以下:算法
關於鎖粗化與鎖細化,在不少關於java優化的書籍都會講解。好比java併發編程(是老胡併發與鎖的啓蒙書)等等。一些讀者在讀Java鎖細節說沒有講解鎖粗化。在你們的要求,老胡只能厚着麪皮寫下本博客了。編程
你們是否以爲十分繞口,鎖粗化,鎖細化在名詞上是兩個對立的。爲何都是優化的方法了?其實能夠想象成長跑,短跑。就行了。api
receiveIntegerNoLock 方法調用了兩個聲明synchronized的方法。數組
public IntegeralInfo receiveIntegerNoLock(Integer addIntegeral) { addIntegeral(addIntegeral); addReceiveNum(); return this; } /** * 增長積分 * * @param addIntegeral */ public synchronized void addIntegeral(Integer addIntegeral) { this.integeralValue += addIntegeral; } /** * 增長簽到次數 */ public synchronized void addReceiveNum() { this.receiveNum++; }
新的receiveInteger方法聲明瞭synchronized。值使用了一個鎖安全
public synchronized IntegeralInfo receiveInteger(Integer addIntegeral) { this.integeralValue += addIntegeral; this.receiveNum++; return this; }
需求,經過連續簽到的天數,計算當次簽到應獲得多少積分,把計算出的積分增長到用戶積分上,並計算除等級。併發
分析以下高併發
public synchronized void continuityReceiveIntegeralAlsoGradeSynchronized(Integer continuityDate) { // 經過天數計算,應該得到多少積分 int addIntegeral = calculationSignIntegeral(continuityDate); // 添加積分 this.integeralValue += addIntegeral; // 計算等級 gradeCalculation(); } public int calculationSignIntegeral(Integer continuityDate) { return continuityDate/1; } /** * 等級計算 */ private void gradeCalculation() { }
最簡單的實現,沒有進行任何的優化。三個操做的代碼放到一個方法裏面。觀察calculationSignIntegeral方法會發現,只是進行數據計算,是一個安全的方法,能夠不用上鎖。gradeCalculation方法在必定程度上也是安全的方法,未實現。這個需求有點複雜,不知道那個大神,能夠分析出來,並實現。性能
public void continuityReceiveIntegeralAlsoGrade(Integer continuityDate) { // 經過天數計算,應該得到多少積分 int addIntegeral = calculationSignIntegeral(continuityDate); // 添加積分 synchronized (this) { this.integeralValue += addIntegeral; } // 計算等級 gradeCalculation(); }
只對須要上鎖的計算出的積分增長到用戶積分上操做進行上鎖,減小的上鎖範圍。縮短持有鎖的時間,從而提升併發性能學習
java api裏面的類,個個都寫得十分優秀。是學習,深刻,理解基礎技術的優質的代碼。解讀java.util.Hashtable的源碼,從而理解public都是線程安全,而非public方法都是線程不安全的。當你看完java.util.Hashtable源碼會發現,全部的public都是線程安全,而非public方法都是線程不安全的。
public都是線程安全,而非public方法都是線程不安全的。這種設計有一下特性
開閉原則(OCP)是面向對象設計中「可複用設計」的基石,是面向對象設計中最重要的原則之一,其它不少的設計原則都是實現開閉原則的一種手段。對於擴展是開放的,對於修改是關閉的,這意味着模塊的行爲是能夠擴展的
按照算法計算出的結果或者數據特性進行分類,分類中的每一個類型都有一把鎖。能夠減小鎖爭奪,更高並行度。
關於分段鎖最簡單的實現仍是在java api中,jdk6的ConcurrentHashMap。 ConcurrentHashMap經過hash算法獲得key的hash值,在與數組長度求餘,餘數是數組下標。下標就是分類的類型 下面連接是一個大神寫的關於jdk6的ConcurrentHashMap源碼解讀,寫得有點亂,可是解讀得十分詳細。請點擊
public class LockUser { static class IntegeralInfo { // 用戶積分 private Integer integeralValue; // 經驗值 private Integer experienceValue; // 簽到 private Integer receiveNum; // 等級 private Integer grade; /** * 添加積分,同時增長簽到次數 * * @param addIntegeral * 須要添加的積分 * @return */ public synchronized IntegeralInfo receiveInteger(Integer addIntegeral) { this.integeralValue += addIntegeral; this.receiveNum++; return this; } public IntegeralInfo receiveIntegerNoLock(Integer addIntegeral) { addIntegeral(addIntegeral); addReceiveNum(); return this; } /** * 增長積分 * * @param addIntegeral */ public synchronized void addIntegeral(Integer addIntegeral) { this.integeralValue += addIntegeral; } /** * 增長簽到次數 */ public synchronized void addReceiveNum() { this.receiveNum++; } public synchronized void continuityReceiveIntegeralAlsoGradeSynchronized(Integer continuityDate) { // 經過天數計算,應該得到多少積分 int addIntegeral = calculationSignIntegeral(continuityDate); // 添加積分 this.integeralValue += addIntegeral; // 計算等級 gradeCalculation(); } public void continuityReceiveIntegeralAlsoGrade(Integer continuityDate) { // 經過天數計算,應該得到多少積分 int addIntegeral = calculationSignIntegeral(continuityDate); // 添加積分 synchronized (this) { this.integeralValue += addIntegeral; } // 計算等級 gradeCalculation(); } public int calculationSignIntegeral(Integer continuityDate) { return 1; } /** * 等級計算 */ private void gradeCalculation() { } } }