This is regarding tryLock()
method in re entrant locks. I am running the below sample code. I understand that this code will run into a deadlock.
import java.util.concurrent.locks.ReentrantLock;
public class TestMain {
public static void main(String[] args) {
ReentrantLock rl=new ReentrantLock();
S t1=new S(rl);
S t2=new S(rl);
Thread t=new Thread(t1);
Thread u=new Thread(t2);
t.start();
u.start();
}
}
class S extends Thread{
ReentrantLock rl;
S(ReentrantLock r){
rl=r;
}
public void run(){
System.out.println("Entry--");
rl.tryLock();
System.out.println("locked1 "+rl.getHoldCount()+" "+Thread.currentThread().getName());
rl.lock();
System.out.println("locked2 "+rl.getHoldCount()+" "+Thread.currentThread().getName());
rl.unlock();
System.out.println("unlocked "+rl.getHoldCount()+" "+Thread.currentThread().getName());
}
}
But here my question is that why the statement after the rl.tryLock()
statement is running for the second thread also. Output is coming as
Entry--
Entry--
locked1 0 Thread-3
locked1 1 Thread-2
locked2 2 Thread-2
unlocked 1 Thread-2
I don't think this line should ever have been printed
"locked2 2 Thread-2"
Like
lock
,tryLock
must also be paired with anunlock
IF it returnstrue
. When usingtryLock
you MUST check the return value and unlock if it was locked, because otherwise it will never be fully unlocked.When it prints the following sequence occurs: [Note this is a possible sequence, between 5 and 8 can be re-arranged because multiple threads are involved and it'll still be correct]
System.out.println("Entry--");
System.out.println("Entry--");
rl.tryLock();
[r1 now locked to Thread-2, count=1]rl.tryLock();
[r1 already locked, returns false]System.out.println("locked1 "+rl.getHoldCount()+" "+Thread.currentThread().getName());
[r1 not held, count is thus 0]System.out.println("locked1 "+rl.getHoldCount()+" "+Thread.currentThread().getName());
[r1 held, count=1]rl.lock();
[r1 already locked, blocks]r1.lock();
[r1 held, count=2]System.out.println("locked2 "+rl.getHoldCount()+" "+Thread.currentThread().getName());
rl.unlock();
[r1 held, count=1]System.out.println("unlocked "+rl.getHoldCount()+" "+Thread.currentThread().getName());
The line
"locked2 2 Thread-2"
is printed because a re-entrant lock can be locked more than once if locked by the holder. So bothtryLock
andlock
succeed, but you unlock only one of them, so the other thread blocks forever.