I am trying to understand lockInterruptibly method. What I have understood so far is: void lockInterruptibly() --> acquires the lock if available and performs normal operations. If lock is not available then thread goes in waiting state and while waiting for the lock object if thread gets interrupted it won't get the lock object. If it is not interrupted then only it will get the lock.
I tried to understand from Java docs API however it's not very clear to me. Could anybody express it in other words?
Also I am unable to understand how come below is the possible output for this program?
Possible output 1)
Before interrupt Hello....
After t1.interrupt Hello and before t2.start()....
exception caught test1
After t2.start Hello but before t2.interrupt....
After t2.interrupt Hello....
exception caught test2
Main Hello....
Main Hello....
Main Hello....
Possible output 2)
Before interrupt Hello....
After t1.interrupt Hello and before t2.start()....
exception caught test1
After t2.start Hello but before t2.interrupt....
After t2.interrupt Hello....
Main Hello....
Main Hello....
Main Hello....
exception caught test2
Program: -
import java.util.concurrent.locks.*;
class Test{
static Lock1 l = new Lock1();
public void test1() throws InterruptedException{
l.lockInterruptibly();
synchronized(l){
for(int i=0; i<100; i++){
System.out.println(Thread.currentThread().getName() +" : " + i);
try{
Thread.sleep(100);
}
catch(InterruptedException e){
System.out.println(Thread.currentThread().getName() + " got interrupted");
}
}
}
}
public void test2() throws InterruptedException{
l.lockInterruptibly();
synchronized(l){
for(int i=100; i>0; i--){
System.out.println(Thread.currentThread().getName() +" : " + i);
try{
Thread.sleep(100);
}
catch(InterruptedException e){
System.out.println(Thread.currentThread().getName() + " got interrupted");
}
}
}
}
}
class MyThread1 extends Thread{
Test t;
MyThread1(String name, Test t){
super(name);
this.t = t;
}
public void run(){
try{
t.test1();
}
catch(InterruptedException e){
System.out.println("exception caught test1");
}
}
}
class MyThread2 extends Thread{
Test t;
MyThread2(String name, Test t){
super(name);
this.t = t;
}
public void run(){
try{
t.test2();
}
catch(InterruptedException e){
System.out.println("exception caught test2");
}
}
}
class Lock1 extends ReentrantLock{
}
public class Main{
public static void main(String[] args) throws InterruptedException {
Test t = new Test();
MyThread1 t1 = new MyThread1("thread1",t);
MyThread2 t2 = new MyThread2("thread2",t);
t1.start();
System.out.println("Before interrupt Hello....");
t1.interrupt();
System.out.println("After t1.interrupt Hello and before t2.start()....");
t2.start();
System.out.println("After t2.start Hello but before t2.interrupt....");
t2.interrupt();
System.out.println("After t2.interrupt Hello....");
System.out.println("Main Hello....");
System.out.println("Main Hello....");
System.out.println("Main Hello....");
}
}
Lastly synchronized blocks synchronized(l)
in test1() and test2()
methods of class Test
are executed as they are holding the monitor of l (as used synchronized keyword) or lock of l (as threads called l.lockInterruptibly();
) before entering synchronized blocks?
The reason why I ask if it is holding monitor of l or lock of l is because in below example:
import java.util.concurrent.locks.*;
class Lock1 extends ReentrantLock{
}
class Main{
public void test() throws InterruptedException{
synchronized(this){
Lock1 m = new Lock1();
System.out.println("line 1");
m.lock();
System.out.println(m.getHoldCount());
System.out.println(m.isHeldByCurrentThread());
System.out.println("line 2");
m.wait();
System.out.println("line 3");
}
}
public static void main(String[] args) throws InterruptedException{
Main t1 = new Main();
t1.test();
}
}
Even though main
thread is holding lock of object m(m.lock())
but it gives IllegalMonitorStateException because it doesn't have monitor of object m
.
Hope my question is easier to understand.