Search code examples
javamultithreadingconcurrencysleepjava-17

Multithreading, concurrency and sleep not working as expected


I have a very simple scenario. The following method tries to get access to a lock, waits for 1 second and eventually releases the lock.

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();
    }
}

I'm running the following test:

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

And I'm getting the following log output:

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

I don't understand why only one thread, in this case Thread-2, is getting access to the lock. I was expecting the rest of the threads to be waiting on the lock.lock(); statement and once Thread-2 released the lock, one of them would get it until all threads did. If I remove the Thread.sleep(1000); line, what I expect happens, but I don't understand why.

What am I missing?

SOLUTION

Based on what Dhrubajyoti Gogoi has answered, I've modified my test method and now is working as expected.

@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();
    }
}

Output

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

Solution

  • You main thread is not waiting for other threads to complete the task. Since you added a delay, the problem becomes more apparent.

    Check Thread#join() and How to wait for a number of threads to complete?