Kid101
Kid101

Reputation: 1470

lockInterruptibly Vs lock

I'm unable to make out the difference. I read this: actual-use-of-lockinterruptibly-for-a-reentrantlock

and wanted to test it. Here goes the code:

public class Test {
public static void main(String[] args){
    Test test = new Test();
    test.inturreptWork();
    //Main group
    System.out.println("Main Thread group: "+Thread.currentThread().getThreadGroup().getName());
    //System group  is the parent of main group. it contains system level threads like finalizer,signal dispatcher,attach listener
    System.out.println("Main Thread group: "+Thread.currentThread().getThreadGroup().getParent());
}

public void inturreptWork(){
    Inturrept inturrept= new Inturrept();
    Thread t1 = new Thread(inturrept,"Thread 1");
    Thread t2 = new Thread(inturrept,"Thread 2");
    Thread t3 = new Thread(inturrept,"Thread 3");
    try{
    t1.start();
    Thread.sleep(1000);
    t2.start();
    Thread.sleep(1000);
    t2.interrupt();
    t3.start();
    t1.join();
    t2.join();
    t3.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    finally {
        System.out.println("Finally");
    }


}

Here is the Inturrept Class

        public class Inturrept implements Runnable {
    Lock lock = new ReentrantLock();

    @Override
    public void run() {
        try {
            System.out.println("Trying to get lock ,Thread name is: " + Thread.currentThread().getName());
            lock.lock();// or   lock.lockInterruptibly();

            System.out.println("Running");
            Thread.sleep(7000);// Use something else to mimic sleep as it throws interrupted exception 
            lock.unlock();// This caused IllegalMonitorStateException 
        } catch (InterruptedException e) {
            System.out.println("I was inturrepted, Thread name is: " + Thread.currentThread().getName());
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

Console Output:

Trying to get lock ,Thread name is: Thread 1
Running
Trying to get lock ,Thread name is: Thread 2
Trying to get lock ,Thread name is: Thread 3
Running
Exception in thread "Thread 1" I was inturrepted, Thread name is: Thread 2
java.lang.IllegalMonitorStateException
    at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261)
    at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:457)
    at com.test.main.Inturrept.run(Inturrept.java:21)
    at java.lang.Thread.run(Thread.java:748)
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at com.test.main.Inturrept.run(Inturrept.java:15)
    at java.lang.Thread.run(Thread.java:748)
Running
Exception in thread "Thread 3" Finallyjava.lang.IllegalMonitorStateException
    at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261)
    at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:457)
    at com.test.main.Inturrept.run(Inturrept.java:21)
    at java.lang.Thread.run(Thread.java:748)

Main Thread group: main
Main Thread group: java.lang.ThreadGroup[name=system,maxpri=10]

As mentioned in the answer "This is the same as with regular lock(). But if another thread interrupts the waiting thread lockInterruptibly() will throw InterruptedException." Even if it's lock.lock() or lock.lockinterruptibly(). The thread gets interrupted. so what's the difference? did i understand something wrong please assist. Also another question I've is why do I see "Exception in thread "Thread 3" in console. It ran as I can see two "runnings" in logs.

Thanks you.

Upvotes: 2

Views: 3741

Answers (1)

gati sahu
gati sahu

Reputation: 2626

lockInterruptibly() first check if thread is interrupted or not.If interrupted then throw InterruptedException

 if (Thread.interrupted())
            throw new InterruptedException();
        if (!tryAcquire(arg))
            doAcquireInterruptibly(arg);

lock.unlock() is calling twice in your code .so it is throwing IllegalMonitorStateException because not same thread is doing unlock.When the thread do the unlock without lock it throw the exception.

 if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();

Thread.sleep causing the interrupt exception.Sleep method throw InterruptedException

void sleep(long millis) throws InterruptedException

Modified code

 public void run() {
try {
    System.out.println("Trying to get lock ,Thread name is: " + Thread.currentThread().getName());
    lock.lock();
    System.out.println("Running");
    //Thread.sleep(7000);

} catch (Exception e) {
    System.out.println("I was inturrepted, Thread name is: " + Thread.currentThread().getName());
    e.printStackTrace();
} finally {
    lock.unlock();
}

}

Upvotes: 3

Related Questions