多线程、并发和睡眠未按预期工作

dek*_*eko 2 java concurrency multithreading sleep java-17

我有一个非常简单的场景。以下方法尝试访问锁,等待 1 秒并最终释放锁。

private final Lock lock = new ReentrantLock();

public void lockAndWait() {

    logger.info("I {} am here", Thread.currentThread().getName());

    lock.lock();

    try {

        logger.info("I {} got the lock", Thread.currentThread().getName());

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

    } finally {
        lock.unlock();
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在运行以下测试:

@Test
public void lockTest() {
    for (int i = 0; i < 10; i++) {
        new Thread(() -> lockAndWait()).start();
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到以下日志输出:

12-10-2023 17:11:04 [Thread-2       ] INFO   I Thread-2 am here
12-10-2023 17:11:04 [Thread-1       ] INFO   I Thread-1 am here
12-10-2023 17:11:04 [Thread-6       ] INFO   I Thread-6 am here
12-10-2023 17:11:04 [Thread-4       ] INFO   I Thread-4 am here
12-10-2023 17:11:04 [Thread-8       ] INFO   I Thread-8 am here
12-10-2023 17:11:04 [Thread-7       ] INFO   I Thread-7 am here
12-10-2023 17:11:04 [Thread-5       ] INFO   I Thread-5 am here
12-10-2023 17:11:04 [Thread-2       ] INFO   I Thread-2 got the lock
12-10-2023 17:11:04 [Thread-3       ] INFO   I Thread-3 am here
12-10-2023 17:11:04 [Thread-10      ] INFO   I Thread-10 am here
12-10-2023 17:11:04 [Thread-9       ] INFO   I Thread-9 am here
Run Code Online (Sandbox Code Playgroud)

我不明白为什么只有一个线程(在本例中为 Thread-2)可以访问该锁。我期望其余线程等待该lock.lock();语句,一旦 Thread-2 释放锁,其中一个线程就会获得该锁,直到所有线程都释放该锁。如果我删除该Thread.sleep(1000);行,就会发生我期望的情况,但我不明白为什么。

我缺少什么?

解决方案

根据 Dhrubajyoti Gogoi 的回答,我修改了我的测试方法,现在正在按预期工作。

@Test
public void policyUsageTest() throws InterruptedException {

    List<Thread> threads = new ArrayList<>();

    for (int i = 0; i < 10; i++) {
        Thread thread = new Thread(() -> lockAndWait());
        thread.start();
        threads.add(thread);
    }

    for (Thread thread : threads) {
        thread.join();
    }
}
Run Code Online (Sandbox Code Playgroud)

输出

12-10-2023 18:08:14 [Thread-1       ] INFO   I Thread-1 am here
12-10-2023 18:08:14 [Thread-5       ] INFO   I Thread-5 am here
12-10-2023 18:08:14 [Thread-2       ] INFO   I Thread-2 am here
12-10-2023 18:08:14 [Thread-9       ] INFO   I Thread-9 am here
12-10-2023 18:08:14 [Thread-4       ] INFO   I Thread-4 am here
12-10-2023 18:08:14 [Thread-7       ] INFO   I Thread-7 am here
12-10-2023 18:08:14 [Thread-3       ] INFO   I Thread-3 am here
12-10-2023 18:08:14 [Thread-8       ] INFO   I Thread-8 am here
12-10-2023 18:08:14 [Thread-10      ] INFO   I Thread-10 am here
12-10-2023 18:08:14 [Thread-6       ] INFO   I Thread-6 am here
12-10-2023 18:08:14 [Thread-1       ] INFO   I Thread-1 got the lock
12-10-2023 18:08:15 [Thread-2       ] INFO   I Thread-2 got the lock
12-10-2023 18:08:16 [Thread-9       ] INFO   I Thread-9 got the lock
12-10-2023 18:08:17 [Thread-5       ] INFO   I Thread-5 got the lock
12-10-2023 18:08:18 [Thread-4       ] INFO   I Thread-4 got the lock
12-10-2023 18:08:19 [Thread-3       ] INFO   I Thread-3 got the lock
12-10-2023 18:08:20 [Thread-7       ] INFO   I Thread-7 got the lock
12-10-2023 18:08:21 [Thread-8       ] INFO   I Thread-8 got the lock
12-10-2023 18:08:22 [Thread-10      ] INFO   I Thread-10 got the lock
12-10-2023 18:08:23 [Thread-6       ] INFO   I Thread-6 got the lock
Run Code Online (Sandbox Code Playgroud)

Dhr*_*goi 5

您的主线程不会等待其他线程完成任务。由于添加了延迟,问题变得更加明显。

检查Thread#join()如何等待多个线程完成?