【Java高併發學習】鎖優化相關建議

鎖優化

1.減少鎖持有時間

如果某個線程持有鎖的時間越長,那麼鎖的競爭程度也就越激烈。
下面所示代碼。直接在method1進行了加鎖,但是隻有方法method2內部需要進行同步操作,將加大鎖的持有時間。
	public synchronized void method1() {
		method2();
		method3();
		method4();
	}
	public void method2() {
		//同步操作
	}
	public void method3() {}
	public void method4() {}
採用以下方法可以有效減少鎖的持有時間。
	public void method1() {
		synchronized(this) {
			method2();
		}
		method3();
		method4();
	}
	public void method2() {}
	public void method3() {}
	public void method4() {}
Patter類中matcher方法:只有在表達式未編譯時,進行局部加鎖。
    /**
     * Creates a matcher that will match the given input against this pattern.
     *
     * @param  input
     *         The character sequence to be matched
     *
     * @return  A new matcher for this pattern
     */
    public Matcher matcher(CharSequence input) {
        if (!compiled) {
            synchronized(this) {
                if (!compiled)
                    compile();
            }
        }
        Matcher m = new Matcher(this, input);
        return m;
    }

2.減小鎖粒度

ConcurrentHashMap內部進一步分了默認16個小的HashMap,即16個SEGMENT段。
對於常用的put操作:先根據hashcode得到該新的數據應該被存放到的段,然後只對該段進行加鎖,並進行put操作。因此默認、理想情況下,可同時讓16個線程同時進行put操作。但如果需要獲取它的全局信息,比如size,就需要獲取該對象所有段的鎖然後進行計算size值。但是ConcurrentHashMap的size()方法並不是總這樣獲取,事實上,它會先利用無鎖方式進行求和,如果失敗纔會採用上述的加鎖方式求值。

3.讀寫分離鎖

用於讀多寫少的環境下,因爲讀操作不影響數據的完整性和一致性,可以運行多線程同時對數據進行讀操作。

4.鎖分離

在隊列操作中,take與put方法分別作用於隊列的兩端進行取、添加數據,互不影響操作。可以分別對他們加鎖,進行鎖分離。

5.鎖粗化

如果某一個鎖對同一個鎖不停地進行請求、同步和釋放,將消耗系統的資源,不利於優化。因此當JVM在遇到一連串地對同一鎖不斷進行請求和釋放的操作時,便會把所有的鎖操作整合成對鎖的一次請求,從而減少對鎖的請求同步次數,稱爲鎖粗化。
private ReentrantLock lock = new ReentrantLock();
	public void method3() {
		int size = 500;
		for(int i = 0; i < size ; i++) {
			synchronized(lock) {
				//doSomething
			}
		}
	}

	private ReentrantLock lock = new ReentrantLock();
	public void method3() {
		int size = 500;
		synchronized(lock) {
			for(int i = 0; i < size ; i++) {
				//doSomething
			}
		}
	}

6.總結



發佈了54 篇原創文章 · 獲贊 3 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章