Why this code never deadlocks when I run it? - java

I'm trying out deadlock concepts in Java Multithreading. I came across a code snippet which could possibly result in deadlock:
public class Deadlock {
double amount = 10.0;
public double deposit(double d) {
amount += d;
return amount;
}
public double withdraw(double d) {
amount -= d;
return amount;
}
public static void transfer(Deadlock from, Deadlock to,double d) {
synchronized(from) {
synchronized(to) {
from.withdraw(d);
try {
System.out.println(Thread.currentThread().getName());
Thread.sleep(5000);
}catch(Exception e){}
to.deposit(d);
System.out.println("Done");
}
}
}
public static void main(String[] args) {
final Deadlock a = new Deadlock();
final Deadlock b = new Deadlock();
Thread t1 = new Thread(new Runnable() {
public void run() {
transfer(a, b, 10.0);
}
});
t1.start();
Thread t2 = new Thread(new Runnable() {
public void run() {
transfer(b, a, 10.0);
}
});
t2.start();
}
}
Basically, the code tries to acquire locks on objects a and b at the same time. However, when I run it, the code always completes successfully. Why doesn't this deadlock?

In order for the deadlock to occur, you need to have something like the following scenario happen:
t1 acquires lock a
t2 acquires lock b
t1 attempts to acquire lock b
t2 attempts to acquire lock a
Can you force this? You can try by moving your sleep statement in between lock acquisitions, but this all has to happen within a window thats not really under your direct control.
Try this:
public static void transfer(DeadLock from, DeadLock to,double d) {
synchronized(from) {
try {
System.out.println(Thread.currentThread().getName() +" acquires lock " +from);
Thread.sleep(5000);
synchronized(to) {
System.out.println(Thread.currentThread().getName() +" acquires lock " +to);
from.withdraw(d);
to.deposit(d);
System.out.println("Done");
}
}catch(Exception e){}
}
}
And to confirm you're in a deadlock, send the SIGQUIT signal to your Java process - the JVM will report the threads in a deadlock

It's simply up to the Thread scheduler if one thread is able to reach both of these
synchronized(from) {
synchronized(to) {
before the other thread reaches the first. Add a big enough sleep between those
synchronized (from) {
try {
Thread.sleep(20L);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
synchronized (to) {
and you should experience deadlock.

First thread that reaches the method transfer will acquire the both the resources(to and from) so fast that that it might not be interleaved with the second thread. Having said that, this code is still prone to deadlock. The below code tries to acquire only first lock long enough to second thread getting scheduled to run:
public static void transfer(Deadlock from, Deadlock to, double d) throws InterruptedException {
synchronized (from) {
Thread.sleep(5000);
synchronized (to) {
from.withdraw(d);
System.out.println(Thread.currentThread().getName());
to.deposit(d);
System.out.println("Done");
}
}
}

sleeping a Thread does not release the locks it holds, while waiting releases the lock
T1 has the locks over both deadlock objects, even during sleeping and only when T1 exists the respective synchronized locks , t2 gets access to it.
So to bring in deadlock, you need to sleep between the sychronized statements.
Also alternatively you can try instead of Thread.sleep(5000); to.wait(5000);

Related

Why does this contrived Java code deadlock?

I'm having a hard time understanding synchronized. Since the first thread doesn't do anything with the object 2, doesn't it "unlock" everything in a second?
public class Uninterruptible {
public static void main(String[] args) throws InterruptedException {
final Object o1 = new Object(); final Object o2 = new Object();
Thread t1 = new Thread() {
public void run() {
try {
synchronized(o1) {
Thread.sleep(1000);
synchronized(o2) {}
}
} catch(InterruptedException e) { System.out.println("t1 interrupted"); }
}
};
Thread t2 = new Thread() {
public void run() {
try {
synchronized(o2) {
Thread.sleep(1000);
synchronized(o1) {}
}
} catch(InterruptedException e) { System.out.println("t2 interrupted"); }
}
};
t1.start(); t2.start();
Thread.sleep(2000);
t1.interrupt(); t2.interrupt();
t1.join(); t2.join();
System.out.println("Donezo!");
}
}
It doesn't matter that the inner synchronized blocks do nothing. Java will still attempt to acquire the lock on the the object specified.
No matter whether you have nothing or a huge amount of processing in the inner synchronized blocks, what you have is the minimal example to create a deadlock: two different threads, each owning the lock on a distinct resource, each attempting to acquire the lock on each other's resource.
The deadlock occurs before either thread even gets to executing the inner synchronized block, because neither thread can get locks on both resources at the same time.
The code winds up doing nothing but hanging, with each thread blocked. Your calls to interrupt are too late to cause an InterruptedException; they only set the "interrupted status" in the Thread. Commenting out Thread.sleep(2000) will let the calls to interrupt catch the Threads while they are still sleeping, before they even attempt to acquire the second lock.

For below program, when threads finish their work, why doesn't main thread stops?

This program works fine by printing alternate numbers via different threads but when all the numbers from 0-9 are printed Why does this program not stop? I have to manually stop my application.
public class EvenOddPrinter implements Runnable{
private AtomicInteger num = new AtomicInteger(0);
private Object lock = new Object();
#Override
public void run() {
synchronized (lock){
while (num.get()<10){
System.out.println(num.getAndAdd(1) + " - "+Thread.currentThread().getName());
lock.notify();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class Executor {
public static void main(String[] args) throws InterruptedException {
EvenOddPrinter eop = new EvenOddPrinter();
Thread t1 = new Thread(eop);
Thread t2 = new Thread(eop);
t1.start();
t2.start();
}
}
that's because in the last Thread getting stuck at wait. notifyAll will notify all waiting thread if any there and release lock.
while (num.get()<10){
// existing implementation
}
lock.notifyAll();
The second thread t2 keeps waiting on the lock in the end, and t1 doesnt do the notify() anymore because the while condition becomes false. You must put a lock.notify(); statement outside of the while loop.
As soon as the number reached 8 the first thread calls notify() and goes to wait(). Second thread then makes the number 9 and calls notify() and goes to wait(). First thread is then not able to go inside the loop as specified in the condition, therefore, it exits the synchronized and block and finishes but second thread is still waiting. There has to be a mechanism to notifyAll() as soon as one of the threads exits the synchronized block which is exactly what I did.
#Override
public void run() {
synchronized (lock){
while (num.get()<10){
System.out.println(num.getAndAdd(1) + " - "+Thread.currentThread().getName());
lock.notify();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock.notifyAll();
}
Also, lock is pointless when I am using AtomicInteger (or the other way round).

Creating my own Java deadlock program

I was trying to create A Java dead lock program . I know in real time we wont be creating any dead lock in thread. Unfortunately I have been asked in one of the interview to writing a "Deadlock program using two threads". So here it is
package Thread.DeadLock;
public class deadLock2 {
static ThreadSample1 t1 = new ThreadSample1();
static ThreadSample2 t2 = new ThreadSample2();
public static void main(String args[]) {
t1.start();
t2.start();
}
public static class ThreadSample1 extends Thread {
public void run() {
System.out.println("In first run method");
try {
System.out.println("Holding lock in first one");
synchronized (t1) {
System.out.println("t1 going to wait for t2");
t1.wait();
System.out.println("t1 finished for waiting");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static class ThreadSample2 extends Thread {
public void run() {
System.out.println("In second run method");
try {
System.out.println("Holding lock for second one");
synchronized (t2) {
System.out.println("t2 going to wait for t1");
t2.wait();
System.out.println("t2 finished for waiting");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
I can see the program is getting stuck. I am assuming that it in deadlock situation. t1.start() waits for t2 to finish its task and t2.start() waits for t1 to finish its task. Now while I try to remove the deadlock by notifying the waiting thread using using t1.notify() I get IllegalMonitorStateException.
Can somebody tell in this situation how to remove the deadlock without causing any situation.
First, this is not deadlock. As you correctly described, deadlock is usually situation when there is circular dependency between two or more threads waiting for resources that is held by other thread.
Here, each thread independently waits for notification on itself which is actually not delivered by anybody else in the system. Even if there is no deadlock.
Secondly, IllegalMonitorStateException means that you try to notify/wait on monitor which is not held by the thread. In other words, there is no synchronized prior to notify/wait.
Third, to achieve real deadlock you can do something like this:
synchronized(t1) {
synchronized(t2) {
t2.wait();
}
t1.notify();
}
and vice versa for the other thread.
You can not call notify()/notifyAll() unless the current thread owns that object's monitor. To do that, you must synchronize on it, as you did with wait()
The Javadocs for wait() mention this:
This method should only be called by a thread that is the owner of this object's monitor. See the notify method for a description of the ways in which a thread can become the owner of a monitor.
Throws:
IllegalMonitorStateException – if the current thread is not the owner of this object's monitor.
And from notify():
A thread becomes the owner of the object's monitor in one of three
ways:
By executing a synchronized instance method of that object.
By executing the body of a synchronized statement that synchronizes on the object.
For objects of type Class, by executing a synchronized static method of that class.
See this answer:
Java Wait and Notify: IllegalMonitorStateException
package pck.pramod.geekforgeeks;
public class ThreadDeadlock {
public static Object Lock1 = new Object();
public static Object Lock2 = new Object();
public static void main(String args[]) {
System.out.println(Lock1.toString() + " " + Lock2.toString());
ThreadDemo1 T1 = new ThreadDemo1(Lock1, Lock2, "T1");
ThreadDemo1 T2 = new ThreadDemo1(Lock2, Lock1, "T2");
T1.start();
T2.start();
}
}
class ThreadDemo1 extends Thread {
Object lock1;
Object lock2;
String name;
public ThreadDemo1(Object lock1, Object lock2, String name) {
this.lock1 = lock1;
this.lock2 = lock2;
this.name = name;
}
public void run() {
synchronized (lock1) {
System.out.println(name + " Holding lock ..." + lock1.toString());
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
System.out.println(name + " Waiting for lock ..." + lock2.toString());
synchronized (lock2) {
System.out.println(name + " Holding lock ..." + lock1.toString() + " " + lock2.toString());
}
}
}
}

common data in two threads

I want to have two threads. One will increment my variable and the other one will show it on the screen just after it is incremented.
I want to use the wait() and notifyAll() functions to do that but I have some problems.
I have written this code, but it stops working at some point (it shows only the first and the last number: 1 and 10).
public class TestClass {
static int x = 0;
public static Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
public void run() {
try {
for(int i = 0; i < 10; i++) {
synchronized (lock) {
lock.wait();
System.out.println(x);
}
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
Thread t2 = new Thread(new Runnable() {
public void run() {
for(int i = 0; i < 10; i++) {
synchronized (lock) {
x++;
lock.notifyAll();
}
}
}
});
t2.start();
}
}
I have tried adding additional notifyAll() in the first thread and wait() in the second one(t2) but it still doesn't work. How can I do that right?
From JavaDoc:
The awakened threads will not be able to proceed until the current
thread relinquishes the lock on this object. The awakened threads will
compete in the usual manner with any other threads that might be
actively competing to synchronize on this object; for example, the
awakened threads enjoy no reliable privilege or disadvantage in being
the next thread to lock this object.
The thread that you just woke up is not guaranteed to acquire the lock immediately, thus you could have the loop that calls notifyAll() run all its iterations before the other gets woken up.
If you want them to alternate, one way is to have each one take turns waiting
Below is a working solution. Key is in adding an additional flag that will indicate whether the writing thread has the right to write. Note final on the lock object, that is a good practice.
public class TestClass
{
private static int x = 0;
private static final Object lock = new Object();
private static boolean canWrite = false;
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
public void run() {
try {
for(int i = 0; i < 10; i++)
{
synchronized(lock)
{
if(!canWrite)
lock.wait();
System.out.println(x);
canWrite = false;
lock.notify();
}
}
}
catch (InterruptedException e) {}
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
try {
for(int i = 0; i < 10; i++)
{
synchronized(lock)
{
x++;
canWrite = true;
lock.notify();
lock.wait();
}
}
} catch (InterruptedException ex) {}
}
});
t1.start();
t2.start();
}
}
The pattern is confusing but if you want to try to control threads, I suppose it's a useful exercise.
Change your code to give your thread a good name e.g. "test1" and "test2", say. Run your program and dig out the process ID for it and run
jstack <pid>
(you can find it in the bin directory of the JDK). This is (perhaps) what you will see:
test1 will be waiting one the
lock.wait();
while test2 will waiting on
lock.wait();
as well.
Start at the first iteration. test2 wins and calls notify, which has no effect at all because nothing is waiting on the lock. test2 then starts waiting.
Now test1 can enter and immediately goes into a wait.
If test1 wins the first time, you can get into a cycle that appears to work.
That is why you get the first number (test2 wins first) or the last number (test1 wins).
That's pretty much what it looks like to me, but your jstack will tell you for sure.
PS: Use CountDownLatch and the concurrency package in general.

Why doesn't thread wait for notify()?

Why doesn't thread wait for notify()? The thread starts and then goes to the waiting pool, but it proceeds to execute after that moment.
public class JavaApplication2 {
public static void main(String [] args) {
ThreadB b = new ThreadB();
synchronized(b) {
b.start();
try {
System.out.println("1");
b.wait();
} catch (InterruptedException e) {}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread {
int total;
#Override
public void run() {
synchronized(this) {
total += 1;
//notify();
}
}
}
You are synchronizing on the thread object itself, which is wrong usage. What happens is that the dying thread-of-execution always calls notify on its Thread object: Thread.join relies on this. Therefore it is clear why you get the same behavior with and without your own notify in there.
Solution: use a separate object for thread coordination; this is the standard practice.
The method notifyAll() is invoked for the Thread object of the terminating thread. This fact is strangely documented in the description of the Thread.join, with the following sentence:
As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
Thus, if you don't explicitly read the description of join, which you don't necessarily have to, you don't get to know the reason for the strange behavior.
You cannot depend on not returning from wait until a notify: "interrupts and spurious wakeups are possible". In general, you should wrap a wait call in a loop while the thread should go on waiting.
If you try your code synchronizing on any object other that ThreadB you will find it never terminates. This is because there is a hidden call to notify.
Although I am not aware of anywhere that this is specified, Thread notifies itself when it ends. This is implicit in the way the join method is implemented. This is the code for join:
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
(From the JDK7 source code)
As you can see, the calls to wait only make sense if somewhere there is a call to notify that is called after the thread ends. The same call to notify is what allows your program to terminate.
You have nested synchronized {} constructs in the two places. These constructs seem doing something weird: the thread does not react into notify at all and only resumes when ThreadB (b) terminates. Remove this:
public class JavaApplication2 {
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();
try {
System.out.println(" ### Waiting for notify");
synchronized (b) {
b.wait();
}
System.out.println(" ### Notified");
} catch (InterruptedException e) {
}
System.out.println("### Total is: " + b.total);
}
}
class ThreadB extends Thread {
int total;
#Override
public void run() {
total += 1;
System.out.println(" *** Ready to notify in 5 secs");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
System.out.println(" *** Notification sent");
synchronized (this) {
notify();
}
System.out.println(" *** 5 sec post notification");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
System.out.println(" *** ThreadB exits");
}
}
The code above probably works correctly: with notify() present the main thread resumes after 5 seconds and before we see the message that ThreadB terminates. With notify() commented out the main thread resumes after 10 seconds and after the message about the termination of the ThreadB because notify() is called anywhay from the other code. Marko Topolnik explains why and from where this "behind the scene" notify() call comes from.
I was doing the same testing on the wait/notify opertaions while reading OCP SE 7, good catch. I think we should let the authoer to explain.

Categories