synchronized鎖和lock鎖 隊列中線程執行順序對比

背景

最近複習一下多線程,上面說到synchronized是將被阻塞的現場放到一個虛擬隊列(Lock-Free無鎖機制)中,而Lock是通過AQS隊列存放阻塞的線程。那synchronized裏的線程默認是怎麼競爭鎖的,Lock又是如何?

之前記錄的結論:

 

思路

開啓一個死循環,然後讓多個線程競爭通一把鎖,被阻塞的線程孜然就會被放到對應的阻塞隊列裏,執行時打印線程的名字,然後根據打印的結果判斷順序

 

先驗證synchronized的情況,創建一個runnable實現類,然後共享成員變量map

public class MyThread implements Runnable{
    Map<String,String> map;

    public Map<String, String> getMap() {
        return map;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (map){
                System.out.println(Thread.currentThread().getName()+"拿到了鎖");
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"結束了");
            }
        }
    }
}

在主方法中執行 

public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        for (int i = 0; i < 10; i++) {
            MyThread myThread = new MyThread();
            myThread.setMap(map);
            Thread thread = new Thread(myThread);
            System.out.println(thread.getName()+"開始啓動了");
            thread.start();
        }
        System.out.println("主線程結束了");
    }

結果:線程競爭結果無順序,可以認爲當一個線程釋放鎖資源時,隊列中的其他線程都在競爭?

Thread-0開始啓動了
Thread-1開始啓動了
Thread-2開始啓動了
Thread-3開始啓動了
Thread-4開始啓動了
Thread-5開始啓動了
Thread-6開始啓動了
Thread-7開始啓動了
Thread-8開始啓動了
Thread-9開始啓動了
主線程結束了
Thread-0拿到了鎖
Thread-0結束了
Thread-9拿到了鎖
Thread-9結束了
Thread-1拿到了鎖
Thread-1結束了
Thread-4拿到了鎖
Thread-4結束了
Thread-6拿到了鎖
Thread-6結束了
Thread-2拿到了鎖
Thread-2結束了
Thread-8拿到了鎖
Thread-8結束了
Thread-7拿到了鎖
Thread-7結束了
Thread-5拿到了鎖
Thread-5結束了
Thread-3拿到了鎖
Thread-3結束了
Thread-5拿到了鎖
Thread-5結束了
Thread-7拿到了鎖
Thread-7結束了
Thread-8拿到了鎖
Thread-8結束了
Thread-2拿到了鎖

 

驗證Lock鎖的情況,通過共享一個ReentrantLock對象。

public class MyThread2 implements  Runnable{
    ReentrantLock reentrantLock ;

    public ReentrantLock getReentrantLock() {
        return reentrantLock;
    }

    public void setReentrantLock(ReentrantLock reentrantLock) {
        this.reentrantLock = reentrantLock;
    }

    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            reentrantLock.lock();
            System.out.println(Thread.currentThread().getName()+"拿到了鎖");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"結束了");
            reentrantLock.unlock();
        }
    }
}

 主線程

public static void main(String[] args) {
        ReentrantLock reentrantLock = new ReentrantLock(false);
        for (int i = 0; i < 5; i++) {
            MyThread2 myThread2 = new MyThread2();
            myThread2.setReentrantLock(reentrantLock);
            Thread thread = new Thread(myThread2);
            System.out.println(thread.getName()+"開始啓動了");
            thread.start();
        }

    }

結果可見,線程執行是有順序的,確實是按照順序不停更換頭結點,循環,有序拿到鎖的。

Thread-0開始啓動了
Thread-1開始啓動了
Thread-2開始啓動了
Thread-3開始啓動了
Thread-4開始啓動了
Thread-1拿到了鎖
Thread-1結束了
Thread-0拿到了鎖
Thread-0結束了
Thread-2拿到了鎖
Thread-2結束了
Thread-3拿到了鎖
Thread-3結束了
Thread-4拿到了鎖
Thread-4結束了
Thread-1拿到了鎖
Thread-1結束了
Thread-0拿到了鎖
Thread-0結束了
Thread-2拿到了鎖
Thread-2結束了
Thread-3拿到了鎖
Thread-3結束了
Thread-4拿到了鎖
Thread-4結束了
Thread-1拿到了鎖
Thread-1結束了
Thread-0拿到了鎖
Thread-0結束了
Thread-2拿到了鎖
Thread-2結束了
Thread-3拿到了鎖
Thread-3結束了
Thread-4拿到了鎖

 

這裏有個疑問就是公平鎖的問題,公平鎖反應的應該是新來的線程是否應該排隊吧,已經在CLH隊列裏的線程就是按照順序執行,跟是否公平無關吧?

這裏證明一下,先讓5個線程都打印完,得以判斷出最初的隊列順序,然後再突然讓5個新的線程去競爭,看看這5個線程是否會排到後面。

public static void main(String[] args) {
        ReentrantLock reentrantLock = new ReentrantLock(false);
        for (int i = 0; i < 5; i++) {
            MyThread2 myThread2 = new MyThread2();
            myThread2.setReentrantLock(reentrantLock);
            Thread thread = new Thread(myThread2);
            System.out.println(thread.getName()+"開始啓動了");
            thread.start();
        }
        try {
            Thread.sleep(3500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("開始加入額外線程");
        for (int i = 0; i < 10; i++) {
            MyThread2 myThread2 = new MyThread2();
            myThread2.setReentrantLock(reentrantLock);
            Thread thread = new Thread(myThread2);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            thread.start();
        }
        System.out.println("主線程結束了");

    }

 設置的Lock鎖爲false,爲不公平鎖

最初順序爲3,2,4,1,0,最後結果成了3,10,5,11,2,12,6,13,4,14,7,1,8等等

根據結果可以發現確實有插隊情況出現了,確實符合理論。

Thread-0開始啓動了
Thread-1開始啓動了
Thread-2開始啓動了
Thread-3開始啓動了
Thread-4開始啓動了
Thread-3拿到了鎖
Thread-3結束了
Thread-2拿到了鎖
Thread-2結束了
Thread-4拿到了鎖
Thread-4結束了
Thread-1拿到了鎖
Thread-1結束了
Thread-0拿到了鎖
Thread-0結束了
Thread-3拿到了鎖
開始加入額外線程
Thread-3結束了
Thread-2拿到了鎖
Thread-2結束了
Thread-4拿到了鎖
Thread-4結束了
Thread-1拿到了鎖
Thread-1結束了
Thread-0拿到了鎖
Thread-0結束了
Thread-3拿到了鎖
Thread-3結束了
Thread-5拿到了鎖
Thread-5結束了
Thread-2拿到了鎖
Thread-2結束了
Thread-6拿到了鎖
Thread-6結束了
Thread-4拿到了鎖
Thread-4結束了
Thread-7拿到了鎖
主線程結束了
Thread-7結束了
Thread-1拿到了鎖
Thread-1結束了
Thread-8拿到了鎖
Thread-8結束了
Thread-0拿到了鎖
Thread-0結束了
Thread-9拿到了鎖
Thread-9結束了
Thread-3拿到了鎖
Thread-3結束了
Thread-10拿到了鎖
Thread-10結束了
Thread-5拿到了鎖
Thread-5結束了
Thread-11拿到了鎖
Thread-11結束了
Thread-2拿到了鎖
Thread-2結束了
Thread-12拿到了鎖
Thread-12結束了
Thread-6拿到了鎖
Thread-6結束了
Thread-13拿到了鎖
Thread-13結束了
Thread-4拿到了鎖
Thread-4結束了
Thread-14拿到了鎖
Thread-14結束了
Thread-7拿到了鎖
Thread-7結束了
Thread-1拿到了鎖
Thread-1結束了
Thread-8拿到了鎖

現在改成ture,也就是公平鎖,看看結果如何

結果顯示不符合預期效果,想了一下,因爲CLH他是一個帶頭結點的雙向鏈表,也就是說他的鏈表是一直在變化的,所以順序肯定不會是固定的,頭結點釋放以後,多個線程同時競爭尾部,然後再依次往前排,順序勢必會打亂。

Thread-0開始啓動了
Thread-1開始啓動了
Thread-2開始啓動了
Thread-3開始啓動了
Thread-4開始啓動了
Thread-3拿到了鎖
Thread-3結束了
Thread-2拿到了鎖
Thread-2結束了
Thread-4拿到了鎖
Thread-4結束了
Thread-1拿到了鎖
Thread-1結束了
Thread-0拿到了鎖
Thread-0結束了
Thread-3拿到了鎖
開始加入額外線程
Thread-3結束了
Thread-2拿到了鎖
Thread-2結束了
Thread-4拿到了鎖
Thread-4結束了
Thread-1拿到了鎖
Thread-1結束了
Thread-0拿到了鎖
Thread-0結束了
Thread-3拿到了鎖
Thread-3結束了
Thread-5拿到了鎖
Thread-5結束了
Thread-2拿到了鎖
Thread-2結束了
Thread-6拿到了鎖
Thread-6結束了
Thread-4拿到了鎖
Thread-4結束了
Thread-7拿到了鎖
主線程結束了
Thread-7結束了
Thread-1拿到了鎖
Thread-1結束了
Thread-8拿到了鎖
Thread-8結束了
Thread-0拿到了鎖
Thread-0結束了
Thread-9拿到了鎖
Thread-9結束了
Thread-3拿到了鎖
Thread-3結束了
Thread-10拿到了鎖
Thread-10結束了
Thread-5拿到了鎖
Thread-5結束了
Thread-11拿到了鎖
Thread-11結束了
Thread-2拿到了鎖
Thread-2結束了
Thread-12拿到了鎖
Thread-12結束了
Thread-6拿到了鎖
Thread-6結束了
Thread-13拿到了鎖
Thread-13結束了
Thread-4拿到了鎖
Thread-4結束了
Thread-14拿到了鎖
Thread-14結束了
Thread-7拿到了鎖
Thread-7結束了
Thread-1拿到了鎖
Thread-1結束了
Thread-8拿到了鎖

 

進一步改造一下ReentrantLock ,打印出他的隊列內的元素。

public class ReentrantLockMine extends ReentrantLock {

    public ReentrantLockMine(boolean fair) {
     super(fair);
 }

                 @Override
         protected Collection<Thread> getQueuedThreads() {   //獲取同步隊列中的線程
                     List<Thread> arrayList = new ArrayList<Thread>(super.getQueuedThreads());
                     Collections.reverse(arrayList);
                     return arrayList;
                 }
 }

這邊也是改一下內部的成員變量

public class MyThread2 implements  Runnable{
    ReentrantLockMine reentrantLock ;

    public ReentrantLock getReentrantLock() {
        return reentrantLock;
    }

    public void setReentrantLock(ReentrantLockMine reentrantLock) {
        this.reentrantLock = reentrantLock;
    }

    @Override
    public void run() {
        while (true){
            reentrantLock.lock();
            System.out.println(Thread.currentThread().getName()+"拿到了鎖,當前隊列:"+((ReentrantLockMine)reentrantLock).getQueuedThreads());

            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"結束了");
            reentrantLock.unlock();
        }
    }
}

測試方法

public static void main(String[] args) {
        ReentrantLockMine reentrantLock = new ReentrantLockMine(false);
        for (int i = 0; i < 5; i++) {
            MyThread2 myThread2 = new MyThread2();
            myThread2.setReentrantLock(reentrantLock);
            Thread thread = new Thread(myThread2);
            System.out.println(thread.getName()+"開始啓動了");
            thread.start();
        }
        try {
            Thread.sleep(1500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("開始加入額外線程");
        for (int i = 0; i < 10; i++) {
            MyThread2 myThread2 = new MyThread2();
            myThread2.setReentrantLock(reentrantLock);
            Thread thread = new Thread(myThread2);
            thread.start();
        }
        System.out.println("主線程結束了");

    }

非公平結果:

可以發現,之後加入的線程全部按照順序排在了後面,0號線程拿到線程後又插隊獲取到鎖,繼續執行,其他線程拿不到鎖。

Thread-0開始啓動了
Thread-1開始啓動了
Thread-2開始啓動了
Thread-3開始啓動了
Thread-4開始啓動了
Thread-0拿到了鎖,當前隊列:[]
Thread-0結束了
Thread-0拿到了鎖,當前隊列:[Thread[Thread-1,5,main], Thread[Thread-4,5,main], Thread[Thread-2,5,main], Thread[Thread-3,5,main]]
Thread-0結束了
Thread-0拿到了鎖,當前隊列:[Thread[Thread-1,5,main], Thread[Thread-4,5,main], Thread[Thread-2,5,main], Thread[Thread-3,5,main]]
開始加入額外線程
主線程結束了
Thread-0結束了
Thread-0拿到了鎖,當前隊列:[Thread[Thread-1,5,main], Thread[Thread-4,5,main], Thread[Thread-2,5,main], Thread[Thread-3,5,main], Thread[Thread-5,5,main], Thread[Thread-7,5,main], Thread[Thread-6,5,main], Thread[Thread-8,5,main], Thread[Thread-12,5,main], Thread[Thread-10,5,main], Thread[Thread-11,5,main], Thread[Thread-9,5,main], Thread[Thread-13,5,main], Thread[Thread-14,5,main]]
Thread-0結束了
Thread-0拿到了鎖,當前隊列:[Thread[Thread-1,5,main], Thread[Thread-4,5,main], Thread[Thread-2,5,main], Thread[Thread-3,5,main], Thread[Thread-5,5,main], Thread[Thread-7,5,main], Thread[Thread-6,5,main], Thread[Thread-8,5,main], Thread[Thread-12,5,main], Thread[Thread-10,5,main], Thread[Thread-11,5,main], Thread[Thread-9,5,main], Thread[Thread-13,5,main], Thread[Thread-14,5,main]]
Thread-0結束了
Thread-0拿到了鎖,當前隊列:[Thread[Thread-1,5,main], Thread[Thread-4,5,main], Thread[Thread-2,5,main], Thread[Thread-3,5,main], Thread[Thread-5,5,main], Thread[Thread-7,5,main], Thread[Thread-6,5,main], Thread[Thread-8,5,main], Thread[Thread-12,5,main], Thread[Thread-10,5,main], Thread[Thread-11,5,main], Thread[Thread-9,5,main], Thread[Thread-13,5,main], Thread[Thread-14,5,main]]

公平鎖結果:

可以發現全部按照隊列順序去執行了,不存在某個線程一直獲取資源,符合預期效果。

Thread-0開始啓動了
Thread-1開始啓動了
Thread-2開始啓動了
Thread-3開始啓動了
Thread-4開始啓動了
Thread-0拿到了鎖,當前隊列:[]
Thread-0結束了
Thread-1拿到了鎖,當前隊列:[Thread[Thread-4,5,main], Thread[Thread-2,5,main], Thread[Thread-3,5,main], Thread[Thread-0,5,main]]
Thread-1結束了
Thread-4拿到了鎖,當前隊列:[Thread[Thread-2,5,main], Thread[Thread-3,5,main], Thread[Thread-0,5,main], Thread[Thread-1,5,main]]
開始加入額外線程
主線程結束了
Thread-4結束了
Thread-2拿到了鎖,當前隊列:[Thread[Thread-3,5,main], Thread[Thread-0,5,main], Thread[Thread-1,5,main], Thread[Thread-5,5,main], Thread[Thread-7,5,main], Thread[Thread-6,5,main], Thread[Thread-8,5,main], Thread[Thread-9,5,main], Thread[Thread-10,5,main], Thread[Thread-11,5,main], Thread[Thread-12,5,main], Thread[Thread-13,5,main], Thread[Thread-14,5,main], Thread[Thread-4,5,main]]
Thread-2結束了
Thread-3拿到了鎖,當前隊列:[Thread[Thread-0,5,main], Thread[Thread-1,5,main], Thread[Thread-5,5,main], Thread[Thread-7,5,main], Thread[Thread-6,5,main], Thread[Thread-8,5,main], Thread[Thread-9,5,main], Thread[Thread-10,5,main], Thread[Thread-11,5,main], Thread[Thread-12,5,main], Thread[Thread-13,5,main], Thread[Thread-14,5,main], Thread[Thread-4,5,main], Thread[Thread-2,5,main]]
Thread-3結束了
Thread-0拿到了鎖,當前隊列:[Thread[Thread-1,5,main], Thread[Thread-5,5,main], Thread[Thread-7,5,main], Thread[Thread-6,5,main], Thread[Thread-8,5,main], Thread[Thread-9,5,main], Thread[Thread-10,5,main], Thread[Thread-11,5,main], Thread[Thread-12,5,main], Thread[Thread-13,5,main], Thread[Thread-14,5,main], Thread[Thread-4,5,main], Thread[Thread-2,5,main], Thread[Thread-3,5,main]]
Thread-0結束了
Thread-1拿到了鎖,當前隊列:[Thread[Thread-5,5,main], Thread[Thread-7,5,main], Thread[Thread-6,5,main], Thread[Thread-8,5,main], Thread[Thread-9,5,main], Thread[Thread-10,5,main], Thread[Thread-11,5,main], Thread[Thread-12,5,main], Thread[Thread-13,5,main], Thread[Thread-14,5,main], Thread[Thread-4,5,main], Thread[Thread-2,5,main], Thread[Thread-3,5,main], Thread[Thread-0,5,main]]
Thread-1結束了
Thread-5拿到了鎖,當前隊列:[Thread[Thread-7,5,main], Thread[Thread-6,5,main], Thread[Thread-8,5,main], Thread[Thread-9,5,main], Thread[Thread-10,5,main], Thread[Thread-11,5,main], Thread[Thread-12,5,main], Thread[Thread-13,5,main], Thread[Thread-14,5,main], Thread[Thread-4,5,main], Thread[Thread-2,5,main], Thread[Thread-3,5,main], Thread[Thread-0,5,main], Thread[Thread-1,5,main]]
Thread-5結束了
Thread-7拿到了鎖,當前隊列:[Thread[Thread-6,5,main], Thread[Thread-8,5,main], Thread[Thread-9,5,main], Thread[Thread-10,5,main], Thread[Thread-11,5,main], Thread[Thread-12,5,main], Thread[Thread-13,5,main], Thread[Thread-14,5,main], Thread[Thread-4,5,main], Thread[Thread-2,5,main], Thread[Thread-3,5,main], Thread[Thread-0,5,main], Thread[Thread-1,5,main], Thread[Thread-5,5,main]]
Thread-7結束了
Thread-6拿到了鎖,當前隊列:[Thread[Thread-8,5,main], Thread[Thread-9,5,main], Thread[Thread-10,5,main], Thread[Thread-11,5,main], Thread[Thread-12,5,main], Thread[Thread-13,5,main], Thread[Thread-14,5,main], Thread[Thread-4,5,main], Thread[Thread-2,5,main], Thread[Thread-3,5,main], Thread[Thread-0,5,main], Thread[Thread-1,5,main], Thread[Thread-5,5,main], Thread[Thread-7,5,main]]
Thread-6結束了
Thread-8拿到了鎖,當前隊列:[Thread[Thread-9,5,main], Thread[Thread-10,5,main], Thread[Thread-11,5,main], Thread[Thread-12,5,main], Thread[Thread-13,5,main], Thread[Thread-14,5,main], Thread[Thread-4,5,main], Thread[Thread-2,5,main], Thread[Thread-3,5,main], Thread[Thread-0,5,main], Thread[Thread-1,5,main], Thread[Thread-5,5,main], Thread[Thread-7,5,main], Thread[Thread-6,5,main]]
Thread-8結束了
Thread-9拿到了鎖,當前隊列:[Thread[Thread-10,5,main], Thread[Thread-11,5,main], Thread[Thread-12,5,main], Thread[Thread-13,5,main], Thread[Thread-14,5,main], Thread[Thread-4,5,main], Thread[Thread-2,5,main], Thread[Thread-3,5,main], Thread[Thread-0,5,main], Thread[Thread-1,5,main], Thread[Thread-5,5,main], Thread[Thread-7,5,main], Thread[Thread-6,5,main], Thread[Thread-8,5,main]]
Thread-9結束了
Thread-10拿到了鎖,當前隊列:[Thread[Thread-11,5,main], Thread[Thread-12,5,main], Thread[Thread-13,5,main], Thread[Thread-14,5,main], Thread[Thread-4,5,main], Thread[Thread-2,5,main], Thread[Thread-3,5,main], Thread[Thread-0,5,main], Thread[Thread-1,5,main], Thread[Thread-5,5,main], Thread[Thread-7,5,main], Thread[Thread-6,5,main], Thread[Thread-8,5,main], Thread[Thread-9,5,main]]
Thread-10結束了
Thread-11拿到了鎖,當前隊列:[Thread[Thread-12,5,main], Thread[Thread-13,5,main], Thread[Thread-14,5,main], Thread[Thread-4,5,main], Thread[Thread-2,5,main], Thread[Thread-3,5,main], Thread[Thread-0,5,main], Thread[Thread-1,5,main], Thread[Thread-5,5,main], Thread[Thread-7,5,main], Thread[Thread-6,5,main], Thread[Thread-8,5,main], Thread[Thread-9,5,main], Thread[Thread-10,5,main]]
Thread-11結束了
Thread-12拿到了鎖,當前隊列:[Thread[Thread-13,5,main], Thread[Thread-14,5,main], Thread[Thread-4,5,main], Thread[Thread-2,5,main], Thread[Thread-3,5,main], Thread[Thread-0,5,main], Thread[Thread-1,5,main], Thread[Thread-5,5,main], Thread[Thread-7,5,main], Thread[Thread-6,5,main], Thread[Thread-8,5,main], Thread[Thread-9,5,main], Thread[Thread-10,5,main], Thread[Thread-11,5,main]]
Thread-12結束了
Thread-13拿到了鎖,當前隊列:[Thread[Thread-14,5,main], Thread[Thread-4,5,main], Thread[Thread-2,5,main], Thread[Thread-3,5,main], Thread[Thread-0,5,main], Thread[Thread-1,5,main], Thread[Thread-5,5,main], Thread[Thread-7,5,main], Thread[Thread-6,5,main], Thread[Thread-8,5,main], Thread[Thread-9,5,main], Thread[Thread-10,5,main], Thread[Thread-11,5,main], Thread[Thread-12,5,main]]
Thread-13結束了
Thread-14拿到了鎖,當前隊列:[Thread[Thread-4,5,main], Thread[Thread-2,5,main], Thread[Thread-3,5,main], Thread[Thread-0,5,main], Thread[Thread-1,5,main], Thread[Thread-5,5,main], Thread[Thread-7,5,main], Thread[Thread-6,5,main], Thread[Thread-8,5,main], Thread[Thread-9,5,main], Thread[Thread-10,5,main], Thread[Thread-11,5,main], Thread[Thread-12,5,main], Thread[Thread-13,5,main]]
Thread-14結束了
Thread-4拿到了鎖,當前隊列:[Thread[Thread-2,5,main], Thread[Thread-3,5,main], Thread[Thread-0,5,main], Thread[Thread-1,5,main], Thread[Thread-5,5,main], Thread[Thread-7,5,main], Thread[Thread-6,5,main], Thread[Thread-8,5,main], Thread[Thread-9,5,main], Thread[Thread-10,5,main], Thread[Thread-11,5,main], Thread[Thread-12,5,main], Thread[Thread-13,5,main], Thread[Thread-14,5,main]]
Thread-4結束了
Thread-2拿到了鎖,當前隊列:[Thread[Thread-3,5,main], Thread[Thread-0,5,main], Thread[Thread-1,5,main], Thread[Thread-5,5,main], Thread[Thread-7,5,main], Thread[Thread-6,5,main], Thread[Thread-8,5,main], Thread[Thread-9,5,main], Thread[Thread-10,5,main], Thread[Thread-11,5,main], Thread[Thread-12,5,main], Thread[Thread-13,5,main], Thread[Thread-14,5,main], Thread[Thread-4,5,main]]
Thread-2結束了
Thread-3拿到了鎖,當前隊列:[Thread[Thread-0,5,main], Thread[Thread-1,5,main], Thread[Thread-5,5,main], Thread[Thread-7,5,main], Thread[Thread-6,5,main], Thread[Thread-8,5,main], Thread[Thread-9,5,main], Thread[Thread-10,5,main], Thread[Thread-11,5,main], Thread[Thread-12,5,main], Thread[Thread-13,5,main], Thread[Thread-14,5,main], Thread[Thread-4,5,main], Thread[Thread-2,5,main]]

結論

synchronized的隊列似乎並不有序,根據Lock-Free的解釋,它屬於一個虛擬的隊列,隊列裏的各個數據都在競爭鎖。

Lock嚴格按照隊列順序執行,若非公平鎖狀態則可能被非隊列中的現場插隊執行,公平鎖狀態下按照隊列順序,只有頭結點纔回去嘗試獲取鎖,和synchronized都在競爭鎖情況相比可能更節省資源?但是同一時刻多線程入隊的順序是不確定的(霧)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章