gpt4 book ai didi

java - 困惑的java ThreadPool和ReentrantLock

转载 作者:行者123 更新时间:2023-12-02 02:52:53 25 4
gpt4 key购买 nike

我得到固定数量的两个线程,然后提交了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 将创建新线程来执行已提交但尚未处理的剩余任务。
  • 根据获得锁的第一个线程的速度,处理尚未调度到其他线程的已提交任务,您最终将得到许多线程,永远等待。

关于java - 困惑的java ThreadPool和ReentrantLock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43535080/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com