Reputation: 53
I get a fixed number of two threads, then submitted 100 tasks, inside which I
used a lock and intentionally leave it unlocked, running result of this code is
sorted number from 1 to 99, this makes me confused:
1) Is it because the thread is reused so that the same thread can acquire it multiple times?
2) If so, lock does not block thread, it still can be reused? What the lock guards is only the lines within its scope.
Please correct me.
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();
}
}
Upvotes: 0
Views: 834
Reputation: 8068
If you modify your code this way you get all the information required to answer your questions by yourself:
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();
}
Output Sample
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
As you can see:
100
numbers but you do output only 99
.ReentrantLock
the first thread which obtained the lock may continue working, because he already owns the lock.Answer for question asked by PO in comment
It is kind of predictable: the CachedThreadPool
will create new Threads
on the fly as required. What happens is:
CachedThreadPool
will create new threads to execute the remaining tasks submitted but not yet processed.Upvotes: 2
Reputation: 403
I would say your analysis is correct.
ReentrantLock
is that the same thread can lock it multiple times. The lock guards not lines, but the locking call itself. If you want that other threads have the ability to acquire the lock, then each lock()
call must have a corresponding unlock()
call.
Upvotes: 0