2020久久超碰欧美精品最新亚洲欧美日韩久久精品,国产福利电影一区二区三区,亚洲欧美日韩一区在线观看,亚洲国产欧美日韩欧美特级,亚洲欧美日韩成人一区久久,欧美日韩精品一区二区三区不卡,国产欧美日韩va另类影音先锋,亚洲欧美日韩久久精品,亚洲欧美日韩国产成人精品影院,亚洲国产欧美日韩精品一区二区三区,欧美日韩国产成人高清视频,日韩久久精品国产免费观看频道,久久人人爽人人爽从片av高清,国产精品综合一区二区

首頁常見問題正文

為什么說Synchronized是非公平鎖?

更新時間:2023-04-11 來源:黑馬程序員 瀏覽量:

IT培訓班

  Synchronized是一種獨占鎖(也稱為互斥鎖),在Java中用于保護共享資源的并發訪問。Synchronized 可以保證同一時刻只有一個線程可以獲取到鎖,從而避免了多個線程同時修改共享資源的問題。然而,Synchronized 是一種非公平鎖,因為它不能保證先請求鎖的線程先獲取鎖。

  當多個線程同時請求一個 Synchronized 鎖時,這些線程會被放入一個等待隊列中,等待獲取鎖。在某個時刻,只有一個線程會從等待隊列中被選擇并獲得鎖,而其他線程仍然需要等待。如果在這個時刻選擇等待時間最長的線程獲得鎖,那么就是公平鎖。但是,Synchronized 是一種非公平鎖,它選擇要獲得鎖的線程是隨機的,而不考慮等待時間的長短。這就意味著一個線程可能會連續獲取到鎖,而其他線程需要一直等待,這就造成了線程的不公平競爭。

  下面是一個使用Synchronized的示例代碼,它模擬了一個銀行賬戶并發存取的情況:

public class BankAccount {
    private int balance;
    
    public synchronized void deposit(int amount) {
        balance += amount;
    }
    
    public synchronized void withdraw(int amount) {
        balance -= amount;
    }
}

  在上面的代碼中,deposit和withdraw方法都是使用Synchronized修飾的,以確保同時只有一個線程可以對 balance進行修改。然而,如果有多個線程同時訪問這個銀行賬戶,并且每個線程都不斷地執行存款和取款操作,那么就會出現線程的競爭,而這種競爭的結果是不公平的,因為Synchronized不保證先請求鎖的線程先獲得鎖。

  為了說明Synchronized是一種非公平鎖,我們可以修改上面的代碼,在deposit和withdraw方法中添加一些延遲,讓不同的線程在不同的時間請求鎖。然后運行多個線程并觀察它們執行的順序和結果。

public class BankAccount {
    private int balance;
    
    public synchronized void deposit(int amount) {
        System.out.println("Thread " + Thread.currentThread().getId() + " is depositing...");
        balance += amount;
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    public synchronized void withdraw(int amount) {
        System.out.println("Thread " + Thread.currentThread().getId() + " is withdrawing...");
        balance -= amount;
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class Main {
    public static void main(String[] args) {
        BankAccount account = new BankAccount();
        for (int i = 1; i <= 5; i++) {
            new Thread(() -> {
                for (int j = 1; j <= 3; j++) {
                    account.deposit(100);
                    account.withdraw(50);
                }
            }).start();
        }
    }
}

  在上面的代碼中,我們創建了5個線程并讓它們同時對一個銀行賬戶進行存款和取款操作。每個線程執行3 次操作,每次操作后都會讓線程睡眠100毫秒。這樣做的目的是讓不同的線程在不同的時間請求鎖,以模擬實際的并發場景。

  運行上面的代碼,可以得到類似下面的輸出:

Thread 14 is depositing...
Thread 14 is withdrawing...
Thread 15 is depositing...
Thread 15 is withdrawing...
Thread 14 is depositing...
Thread 14 is withdrawing...
Thread 15 is depositing...
Thread 15 is withdrawing...
Thread 13 is depositing...
Thread 13 is withdrawing...
Thread 12 is depositing...
Thread 12 is withdrawing...
Thread 13 is depositing...
Thread 13 is withdrawing...
Thread 12 is depositing...
Thread 12 is withdrawing...
Thread 11 is depositing...
Thread 11 is withdrawing...
Thread 11 is depositing...
Thread 11 is withdrawing...

  從輸出可以看出,不同的線程交替執行,但有些線程連續執行了多次,而其他線程則需要等待很長時間才能獲得鎖。這就說明了Synchronized是一種非公平鎖,它不能保證先請求鎖的線程先獲取鎖。

分享到:
在線咨詢 我要報名
和我們在線交談!