synchronized和lock的區別

原文摘自: https://www.eyesmoons.com/article/75

1,原始構成

synchronized是關鍵字,屬於JVM層面,經過wait,notify和notifyAll來調度線程。java

Lock是具體類,是api層面的鎖。api

2,使用方法

synchronized不須要用戶手動去釋放鎖, 當synchronized代碼執行完後,系統會自動釋放鎖。多線程

Lock須要用戶手動釋放鎖,不然會出現死鎖現象。須要lock和unlock配合try/finally語句塊來完成。spa

3,等待是否中斷

synchronized不可中斷,除非拋出異常或者正常運行完畢。線程

Lock可中斷,能夠設置超時方法或者調用中斷方法。code

4,加鎖是否公平

synchronized非公平鎖。blog

Lock默認非公平鎖,可指定爲公平鎖。get

5,鎖綁定多個條件condition

synchronized沒有。it

Lock用來分組喚醒須要喚醒的線程,能夠精確喚醒,而不是像synchronized同樣要麼隨機喚醒一個線程,要麼所有喚醒。io

 

Demo: 練習

  多線程之間按順序調用,實現A->B->C三個線程啓動,要求:AA打印5次,BB打印10次,CC打印15次,重複10遍。

package com.demo.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class ShareResource{
    int number = 1;
    private Lock lock = new ReentrantLock();
    
    private Condition c1 = lock.newCondition();
    private Condition c2 = lock.newCondition();
    private Condition c3 = lock.newCondition();
    
    public void print5(){
        lock.lock();
        try {
            while(number!=1){
                c1.await();
            }
            for(int i=1;i<=5;i++){
                System.out.println(Thread.currentThread().getName()+"\t"+i);
            }
            number = 2;
            c2.signal();
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            lock.unlock();
        }
    }
    
    public void print10(){
        lock.lock();
        try {
            while(number!=2){
                c2.await();
            }
            for(int i=1;i<=10;i++){
                System.out.println(Thread.currentThread().getName()+"\t"+i);
            }
            number = 3;
            c3.signal();
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            lock.unlock();
        }
    }
    
    public void print15(){
        lock.lock();
        try {
            while(number!=3){
                c3.await();
            }
            for(int i=1;i<=15;i++){
                System.out.println(Thread.currentThread().getName()+"\t"+i);
            }
            number = 1;
            c1.signal();
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            lock.unlock();
        }
    }
}
public class TestReentrantLock {

    public static void main(String[] args) {
        ShareResource shareResource = new ShareResource();
        
        new Thread(()->{
            for(int i=1;i<=10;i++){
                shareResource.print5();
            }
        },"AA").start();
        
        new Thread(()->{
            for(int i=1;i<=10;i++){
                shareResource.print10();
            }
        },"BB").start();
        
        new Thread(()->{
            for(int i=1;i<=10;i++){
                shareResource.print15();
            }
        },"CC").start();
    }
}
相關文章
相關標籤/搜索