java面試-synchronized與lock有什么區別?


1、原始構成:

synchronized是關鍵字,屬於JVM層面,底層是由一對monitorenter和monitorexit指令實現的。

ReentrantLock是一個具體類,是API層面的鎖。

2、使用方法:

synchronized不需要用戶手動釋放鎖,當synchronized代碼塊執行完成后,系統會自動讓線程釋放對鎖的占用

ReentrantLock需要用戶手動釋放鎖,若沒有手動釋放可能導致死鎖現象。

3、等待是否可中斷:

synchronized不可中斷,除非拋出異常或者正常運行完成

ReentrantLock可中斷

4、加鎖是否公平:

synchronized非公平鎖

ReentrantLock兩者都可以,默認是非公平鎖。

5、鎖綁定多個條件Condition:

synchronized沒有。

ReentrantLock可用來分組喚醒需要喚醒的線程。而不是像synchronized要么隨機喚醒一個線程,要么喚醒所有線程。

 題目:多線程之間按順序調用,實現A->B->C三個線程啟動,要求如下

* AA打印5次,BB打印10次,CC打印15次
* 緊接着
* AA打印5次,BB打印10次,CC打印15次
* 來10輪
class ShareResource {
    private int number = 1;
    private Lock lock = new ReentrantLock();
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private Condition condition3 = lock.newCondition();

    public void print5() {
        lock.lock();
        try {
            while (number != 1) {
                condition1.await();
            }
            for (int i = 1; i <= 5; i++) {
                System.out.println(Thread.currentThread().getName() + " " + i);
            }
            number = 2;
            condition2.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }


    public void print10() {
        lock.lock();
        try {
            while (number != 2) {
                condition2.await();
            }
            for (int i = 1; i <= 10; i++) {
                System.out.println(Thread.currentThread().getName() + " " + i);
            }
            number = 3;
            condition3.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }


    public void print15() {
        lock.lock();
        try {
            while (number != 3) {
                condition3.await();
            }
            for (int i = 1; i <= 15; i++) {
                System.out.println(Thread.currentThread().getName() + " " + i);
            }
            number = 1;
            condition1.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

public class SyncAndReentrantLockDemo {

    public static void main(String[] args) {
        ShareResource shareResource = new ShareResource();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                shareResource.print5();
            }
        }, "AAA").start();

        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                shareResource.print10();
            }
        }, "BBB").start();

        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                shareResource.print15();
            }
        }, "CCC").start();
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM