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.
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();
}
}
Related
The code use Java 8:
public class MustDeadLock {
private static final Object obj1 = new Object();
private static final Object obj2 = new Object();
public static void main(String[] args) {
mockDeadLock();
}
public static void mockDeadLock() {
CompletableFuture cf1 = CompletableFuture.runAsync(() -> {
synchronized (obj1) {
System.out.println("thread A got lock: obj1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("thread A ready to get the rest lock");
synchronized (obj2) {
System.out.println("thread A got all locks");
}
}
});
CompletableFuture cf2 = CompletableFuture.runAsync(() -> {
synchronized (obj2) {
System.out.println("thread B got lock: obj2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("thread B ready to get the rest lock");
synchronized (obj1) {
System.out.println("thread B got all locks");
}
}
});
CompletableFuture.allOf(cf1, cf2);
System.out.println("program ready to terminate");
}
}
I'm wondering why
System.out.println("thread A ready to get the rest lock");
and
System.out.println("thread B ready to get the rest lock");)
don't get executed.
Why does it just print:
thread B got lock: obj2
thread A got lock: obj1
program ready to terminate
and then terminate the program rather than blocking?
Simply because your main thread continues the execution while the other threads are sleeping.
If you want to wait for these threads to complete before continuing the execution, you can for example join them before the end of the method:
// rest of the program
cf1.join();
cf2.join();
System.out.println("program ready to terminate");
This will print:
thread B got lock: obj2
thread A got lock: obj1
thread B ready to get the rest lock
thread A ready to get the rest lock
This will produce the deadlock and the program will never terminate.
I would like to make a simple thread program that starts 3 threads in order 1,2,3 and after that stops in order 3,2,1 just by using the sleep() method. However, everytime the threads start in different order.
class Thread1 extends Thread{
public void run(){
System.out.println("Thread 1 running...");
try {
this.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Thread 1 has terminated");
}
}
class Thread2 extends Thread {
public void run(){
System.out.println("Thread 2 running...");
try {
this.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Thread 2 has terminated");
}
}
class Thread3 extends Thread {
public void run(){
System.out.println("Thread 3 running...");
try {
this.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Thread 3 has terminated");
}
}
public static void main(String[] args) throws InterruptedException {
Thread tr1 = new Thread1();
Thread tr2 = new Thread2();
Thread tr3 = new Thread3();
tr1.start();
tr2.start();
tr3.start();
}
current output:
Thread 1 running...
Thread 3 running...
Thread 2 running...
Thread 3 has terminated
Thread 2 has terminated
Thread 1 has terminated
desired output:
Thread 1 running...
Thread 2 running...
Thread 3 running...
Thread 3 has terminated
Thread 2 has terminated
Thread 1 has terminated
Your threads are started in right order, but output can be wrong because output messages arrive concurrently. You should move messaging into the main thread:
public static void main(String[] args) throws InterruptedException {
Thread tr1 = new Thread1();
Thread tr2 = new Thread2();
Thread tr3 = new Thread3();
tr1.start();
System.out.println("Thread 1 started");
tr2.start();
System.out.println("Thread 2 started");
tr3.start();
System.out.println("Thread 3 started");
}
You can make Util class, witch must be thread safe, and make synchronized method to print.
public class Utils {
public static synchronized void printStuff(String msg) {
System.out.println(msg);
}
}
Now in Thread1, Thread2 and Thread3 use this Utils.printStuff("Text") to print in console.
I am learning threading in java. As per the description of finally block in an Oracle tutorial:
Note: If the JVM exits while the try or catch code is being executed, then the finally block may not execute. Likewise, if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.
So I tried to interrupt a thread in try catch block and check whether finally is executed in following class. But as per the output of the program, finally block is executed. Can someone explain what happened?
package com.lock;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestLock{
public static void main(String[] args) throws InterruptedException {
MyThread lockT= new MyThread();
Thread t= new Thread(lockT);
t.setName("TempThread1");
t.start();
Thread.sleep(1000);
t.interrupt();
}
}
class MyThread implements Runnable {
Lock lock;
public MyThread() {
lock= new ReentrantLock();
}
#Override
public void run() {
try {
if(lock.tryLock()){
Thread.sleep(5000);
while (!Thread.currentThread().isInterrupted()) {
System.out.println("My thread name is "+ Thread.currentThread().getName());
}
}
} catch (Exception e) {
e.printStackTrace();
}finally{
System.out.println("finally ");
lock.unlock();
}
}
}
The rule here is saying: may not execute which does not mean it will not execute.
So basically the rule is saying: don't rely that the finally block will be executed, we don't provide such guarantees.
I know it's a old thread but I'd like to present a situation where the threads get interrupted and doesn't execute finally: Here is the sample code:
public class Test {
public static void main(String[] args) {
Test test = new Test();
test.LockWork();
}public void LockWork() {
WithLock withLock = new WithLock();
Thread t1 = new Thread(() -> {
withLock.produce();
});
Thread t2 = new Thread(() -> {
withLock.consume();
});
ExecutorService service= Executors.newCachedThreadPool(new WithLockThreadFactory());
Future f1=service.submit(t1);
Future f2=service.submit(t2);
//f1.cancel(true);
try {
System.out.println("-------------------------------------sleeping now-------------------------------------");
Thread.sleep(3000);
System.out.println("-------------------------------------Intereputing Producer-------------------------------------");
f1.cancel(true);
service.shutdown();
Thread.sleep(1000);
System.out.println("is Producer done: "+f1.isDone());
service.awaitTermination(1, TimeUnit.DAYS);
System.out.println("is Consumer done: "+f2.isDone());
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Ending Program");
}
now There is my Thread Factory:
public class WithLockThreadFactory implements ThreadFactory {
private int counter;
public WithLockThreadFactory() {
this.counter = 1;
}
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "WithLockThreadFactoryThread " + counter);
counter++;
return t;
}
now WithLock Class:
public class WithLock {
ReentrantLock lock = new ReentrantLock(true);
LinkedList<Integer> linkedList = new LinkedList<>();
Condition isEmpty = lock.newCondition();
Condition isFull = lock.newCondition();
int limit = 10;
volatile int interruptCounter = 0;
public void produce() {
System.out.println("WithLock.produce() Name: " + Thread.currentThread().getName());
try {
int value = 1;
while (true) {
lock.lockInterruptibly();
if (limit == linkedList.size()) {
System.out.println("acquiring lock in produce");
isEmpty.await(3000, TimeUnit.MILLISECONDS);
}
linkedList.add(value % limit);
System.out.println("value added to list: " + value % limit);
value++;
isFull.signal();
System.out.println("notifiedy lock in produce");
lock.unlock();
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("I was interupted Producer");
interruptCounter++;
System.out.println("interruptCounter value :" + interruptCounter);
} finally {
lock.unlock();
System.out.println("Finally Unlocked Producuer");
}
System.out.println("Ending things now: Producer");
}
public void consume() {
System.out.println("WithLock.consume() Name: " + Thread.currentThread().getName());
try {
while (true) {
lock.lockInterruptibly();
// no use as poll doesn't throw an exception if the queue is
// empty
if (linkedList.size() == 0) {
System.out.println("acquiring lock in consume");
isFull.await(3000, TimeUnit.MILLISECONDS);
if (interruptCounter > 2) {
break;
}
}
System.out.println("removing element from queue: " + linkedList.poll());
isEmpty.signal();
System.out.println("notifiedy lock in consume");
lock.unlock();
Thread.sleep(1000);
if (interruptCounter != 0) {
interruptCounter++;
}
}
} catch (InterruptedException e) {
System.out.println("I was Interupted Consumer");
} finally {
lock.unlock();
System.out.println("Finally Unlocked Consumer");
}
System.out.println("Ending things now: Consume");
}
}
and this is the output in the console:
-------------------------------------sleeping now-------------------------------------
WithLock.produce() Name: WithLockThreadFactoryThread 1
WithLock.consume() Name: WithLockThreadFactoryThread 2
value added to list: 1
notifiedy lock in produce
removing element from queue: 1
notifiedy lock in consume
acquiring lock in consume
value added to list: 2
notifiedy lock in produce
removing element from queue: 2
notifiedy lock in consume
acquiring lock in consume
value added to list: 3
notifiedy lock in produce
removing element from queue: 3
notifiedy lock in consume
-------------------------------------Intereputing Producer-------------------------------------
I was interupted Producer
interruptCounter value :1
acquiring lock in consume
is Producer done: true
removing element from queue: null
notifiedy lock in consume
acquiring lock in consume
Finally Unlocked Consumer
Ending things now: Consume
is Consumer done: true
Ending Program
This is something I found interesting and wanted to share. I tried it in JAVA8.
If the JVM exits...
Try System.exit() call...
First and foremost, Oracle's tutorials are descriptive and not normative. Your quote should by no means be taken as specification of behavior.
The thread can be interrupted while executing the finally block, in which case the said finally block may indeed fail to complete. This is, however, fully under your control and you can always write such a finally which is not susceptible to this happening.
Rest assured that the finally block will not be skipped over due to a regular InterruptedException occurring within its try block.
If a thread is being repeatedly stop()ped, however, it will be harder to ensure the finally block executes.
class JoinDemo extends Thread {
JoinDemo(String nm) {
setName(nm);
start();
}
public void run() {
for (int i = 1; i <= 5; i++) {
try {
Thread.sleep(100);
} catch (Exception e) {
System.out.println(e);
}
System.out.println(i);
}
System.out.println(getName() + " exiting.");
}
public static void main(String args[]) {
JoinDemo t1 = new JoinDemo("One");
JoinDemo t2 = new JoinDemo("Two");
JoinDemo t3 = new JoinDemo("Three");
try {
t1.join();
} catch (Exception e) {
System.out.println(e);
}
System.out.println("Main Thread Exits now.");
}
}
The output obtained is:
1
1
1
2
2
2
3
3
3
4
4
4
5
5
Three exiting.
One exiting.
5
Main Thread Exiting
Two exiting.
I wrote the above program after going through various sites to understand the concept of Join(). But still i'm unable to get it.The problem I'm facing is that I have used t1.join(). So thread one should exit before three, but here thread three exits before one. And every time I run the program the output is different. As sometimes it is two exiting before one, or three before one. Shouldn't thread one exit before any other thread?? As t1.join() waits for thread one to terminate before three and one??
No you mistook the effect of join().
when you do a t1.join()you are just asserting that the thread t1 will be finished before continuing the program.
As you can see it's what you have,
One exiting.
5
Main Thread Exiting
One exit before the end of the main symbolized by the Main Thread Exiting.
If you want your program to finish all the thread before finishing you should do :
try {
t1.join();
t2.join();
t3.join();
} catch (Exception e) {
System.out.println(e);
}
If you want One to finish then 2 then 3
JoinDemo t1 = new JoinDemo("One");
try {
t1.join();
} catch (Exception e) { System.out.println(e); }
JoinDemo t2 = new JoinDemo("Two");
try {
t2.join();
} catch (Exception e) { System.out.println(e); }
JoinDemo t3 = new JoinDemo("Three");
try {
t3.join();
} catch (Exception e) { System.out.println(e); }
To know exactly what join() is doing,
JoinDemo t1=new JoinDemo("One");
t1.join();
JoinDemo t2=new JoinDemo("Two");
JoinDemo t3=new JoinDemo("Three");
Just call the method after declaring t1 and see.
join() method will make the already initialized Thread to complete first.So other Threads will wait till then.
t1.join() simply ensures that your main thread will block until t1 has completed. You have no control over how quickly t1 will finish compared to the other two threads.
t1, t2 and t3 are at the mercy of the thread scheduler. The only guarantee you have in your code is that t1 will finish before the main thread.
You are running 3 different threads. The priority or amount of CPU used for each thread depends on the java implementation, in some cases it's done by the OS. That's why you get a different output.
Joins makes the running thread wait until the joint thread dies.
I think you want this output:
class JoinDemo extends Thread {
JoinDemo(String nm) {
setName(nm);
}
public void run() {
for (int i = 1; i <= 5; i++) {
try {
Thread.sleep(100);
} catch (Exception e) {
System.out.println(e);
}
System.out.println(i);
}
System.out.println(getName() + " exiting.");
}
public static void main(String args[]) {
JoinDemo t1 = new JoinDemo("One");
JoinDemo t2 = new JoinDemo("Two");
JoinDemo t3 = new JoinDemo("Three");
try {
t1.start();
t1.join();
t2.start();
t2.join();
t3.start();
t3.join();
} catch (Exception e) {
System.out.println(e);
}
System.out.println("Main Thread Exits now.");
}
}
I wanted to verify in my own eyes the different between sleep and wait.
Wait can only be done in a synchronized block because it releases the ownership of the monitor lock.
While sleep is not related to the monitor lock and a thread that is already the owner of the monitor lock shouldn't lose its ownership if sleeping.
For that i made a test:
Steps:
Started a thread that waits in a synched block for 5 secs.
Waited 3 secs and started another thread that acquires the monitor lock (because Thread-A is waiting) and simply sleeps for 5 secs while holding the monitor lock.
Expected result:
Thread - A will only re-acquire the lock after 8 seconds, When Thread - B finally releases the monitor lock by exiting the synch block.
Actual result.
Thread - A acquires the monitor lock after 5 seconds.
Can some1 explain to me what happened here?
public static void main(String[] args) {
Runnable r1 = new Runnable() {
#Override
public void run() {
System.out.println("r1 before synch block");
synchronized (this) {
System.out.println("r1 entered synch block");
try {
wait(5000);
System.out.println("r1 finished waiting");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Runnable r2 = new Runnable() {
#Override
public void run() {
System.out.println("r2 before synch block");
synchronized (this) {
System.out.println("r2 entered synch block");
try {
Thread.currentThread();
Thread.sleep(5000);
//wait(5000);
System.out.println("r2 finished waiting");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
try {
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
Thread.currentThread();
Thread.sleep(3000);
t2.start();
t1.join();
t2.join();
System.out.println(Thread.currentThread().getName() + " Finished joining");
} catch (Exception e) {
e.printStackTrace();
}
}
EDIT:
Ok I understand my error - I waiting on this - r1/r2 and not on the same object.
Now I changed it and both acquire on the same object - The class instance of Main.
1. r1 acquires ownership of the monitor lock of Main.this
2. r1 Releases it.
3. When r1 tries to re-acquire it I get an exception:
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at Main$1.run(Main.java:28)
at java.lang.Thread.run(Unknown Source)
on synchronized (Main.this)
What is the problem here?
public static void main(String[] args) {
Main main = new Main();
main.test();
}
public void test() {
Runnable r1 = new Runnable() {
#Override
public void run() {
System.out.println("r1 before synch block");
synchronized (Main.this) {
System.out.println("r1 entered synch block");
try {
wait(5000);
System.out.println("r1 finished waiting");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Runnable r2 = new Runnable() {
#Override
public void run() {
System.out.println("r2 before synch block");
synchronized (Main.this) {
System.out.println("r2 entered synch block");
try {
Thread.currentThread();
Thread.sleep(5000);
//wait(5000);
System.out.println("r2 finished waiting");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
try {
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
Thread.currentThread();
Thread.sleep(3000);
t2.start();
t1.join();
t2.join();
System.out.println(Thread.currentThread().getName() + " Finished joining");
} catch (Exception e) {
e.printStackTrace();
}
}
The two threads actually hold two different locks. Say your class name is MyClass, change two lines of synchronized (this) to synchronized (MyClass.this), that makes the two threads to hold same lock.
here's a much better way to make the test work , and show that it works .
your problem was that you didn't wait correctly and used Thread.currentThread() for no reason .
btw, in case you want to use signalling of the wait-notifier mechanism without losing the signal , i suggest you read this link.
public class MAIN
{
public static void main(final String[] args)
{
final Object sync =new Object();
final long startTime=System.currentTimeMillis();
final Runnable r1=new Runnable()
{
#Override
public void run()
{
System.out.println((System.currentTimeMillis()-startTime)/1000+": r1 before synch block");
synchronized(sync)
{
System.out.println((System.currentTimeMillis()-startTime)/1000+": r1 entered synch block");
try
{
sync.wait(5000);
System.out.println((System.currentTimeMillis()-startTime)/1000+": r1 finished waiting");
}
catch(final InterruptedException e)
{
e.printStackTrace();
}
}
System.out.println((System.currentTimeMillis()-startTime)/1000+": r1 exited synch block");
}
};
final Runnable r2=new Runnable()
{
#Override
public void run()
{
System.out.println((System.currentTimeMillis()-startTime)/1000+": r2 before synch block");
synchronized(sync)
{
System.out.println((System.currentTimeMillis()-startTime)/1000+": r2 entered synch block");
try
{
Thread.sleep(5000);
System.out.println((System.currentTimeMillis()-startTime)/1000+": r2 finished waiting");
}
catch(final InterruptedException e)
{
e.printStackTrace();
}
}
System.out.println((System.currentTimeMillis()-startTime)/1000+": r2 exited synch block");
}
};
try
{
final Thread t1=new Thread(r1);
final Thread t2=new Thread(r2);
t1.start();
Thread.sleep(3000);
t2.start();
t1.join();
t2.join();
System.out.println((System.currentTimeMillis()-startTime)/1000+": Finished joining");
}
catch(final Exception e)
{
e.printStackTrace();
}
}
}