簡體   English   中英

困惑的Java ThreadPool和ReentrantLock

[英]Confused java ThreadPool and ReentrantLock

我得到兩個線程的固定數量,然后提交了100個任務,在其中

使用了一個鎖並有意使其保持解鎖狀態,此代碼的運行結果是

從1到99的數字排序,這讓我感到困惑:

1)是因為線程被重用,以便同一線程可以多次獲取它嗎?

2)如果是這樣,鎖不阻塞線程,它還能被重用嗎? 鎖保護的只是其范圍內的行。

請糾正我。

public class LockTest {

    public static volatile int a = 1;

    static final ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        for (int k = 0; k < 100; k++) {
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    lock.lock();
                    System.out.println(a++);
                }
            });
        }
        executorService.shutdown();
    }
}

如果以這種方式修改代碼,您將獲得自己回答問題所需的所有信息:

public static void main(String[] args) {
    ExecutorService executorService = newFixedThreadPool(2);
    for (int k = 0; k < 100; k++) {
        executorService.submit(() -> {
            lock.lock();
            System.out.println(currentThread().getId() +
                             " hold count: " + lock.getHoldCount());
            System.out.println("a = " + a++);
        });
    }
    executorService.shutdown();
}

輸出樣本

12 hold count: 1
a = 1
12 hold count: 2
a = 2
12 hold count: 3
a = 3
...
12 hold count: 98
a = 98
12 hold count: 99
a = 99

如你看到的:

  • 您想輸出100數字,但只輸出99
  • 輸出顯示只有一個線程在工作,因為您永遠不會釋放獲得的第一個線程的鎖。 第二個線程等待獲取鎖。
  • 因為您使用ReentrantLock ,所以獲得該鎖的第一個線程可能會繼續工作,因為他已經擁有該鎖。
  • JVM將永遠不會關閉,因為第一個線程將永遠不會釋放鎖,因此第二個線程將永遠等待。

PO在評論中提出的問題的答案

這是可以預見的: CachedThreadPool將根據需要CachedThreadPool創建新的Threads 發生的是:

  • 第一個線程將永遠獲得該鎖(因為它永遠不會釋放它)。 它將盡快處理提交的任務。
  • 當第一個線程正在處理時, CachedThreadPool將創建新線程以執行已提交但尚未處理的其余任務。
  • 根據獲得鎖定的第一個線程的速度,處理尚未調度到其他線程的已提交任務,您最終將擁有許多線程,並永遠等待。

我會說你的分析是正確的。

  1. 是的,獲取鎖的第一個線程持有該鎖。 第二個線程在鎖定調用時阻塞。
  2. 是的, ReentrantLock的要點是同一線程可以多次鎖定它。 鎖不保護線路,而是鎖本身。

如果希望其他線程具有獲取鎖的能力,則每個lock()調用必須具有一個對應的unlock()調用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM