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
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?