java mulithreading deadlock - java

I was asked to created a dead lock situation. Below code is never creating me dead lock although there is a chance of getting dead lock.
The reason is as follows.
If method1() and method2() both will be called by two or many threads , there is a good chance of deadlock because if thead 1 aquires lock on Sting object while executing method1() and thread 2 acquires lock on Integer object while executing method2() both will be waiting for each other to release lock on Integer and String to proceed further which will never happen.
I wanted to create a dead lock situation but is not creating it.
class Task implements Runnable {
public void method1() {
synchronized (String.class) {
System.out.println("Aquired lock on String.class object");
synchronized (Integer.class) {
System.out.println("Aquired lock on Integer.class object");
}
}
}
public void method2() {
synchronized (Integer.class) {
System.out.println("Aquired lock on Integer.class object");
synchronized (String.class) {
System.out.println("Aquired lock on String.class object");
}
}
}
#Override
public void run() {
method1();
method2();
}
}
public class DeadLock {
public static void main(String args[]) {
Runnable r= new Task();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
}
}

If you want to increase the chance for deadlock, you can sleep the thread after it acquires the first lock, and before it tries to acquires the second lock. One rough example:
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
public void run() {
synchronized (String.class) {
System.out.println("Thread 1 after acquiring String lock");
Thread.sleep(5000); // Sleep for 5 seconds
synchronized (Integer.class) {
System.out.println("Thread 1 after acquiring Integer lock");
}
}
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
synchronized (Integer.class) {
System.out.println("Thread 2 after acquiring Integer lock");
Thread.sleep(5000); // Sleep for 5 seconds
synchronized (String.class) {
System.out.println("Thread 2 after acquiring String lock");
}
}
}
});
t1.start();
t2.start();
}
You will see:
Thread 1 after acquiring String lock
Thread 2 after acquiring Integer lock
or
Thread 2 after acquiring Integer lock
Thread 1 after acquiring String lock
and then deadlock happens.

This is unlikely create a deadlock, as the Task always attempts method1 then method2. You need to have 2 different runnables which call method1 and method2 in opposing orders. Additionally, you probably should consider using a countdown latch that your tasks must wait for at the beginning of run() to provide a higher probability of the 2 threads actually executing concurrently.

Related

Why am I getting IllegalMonitorStateException for the Thread t1

I'm getting this error for the code below
First thread about to sleep
thread 1 run
Boolean assignment done.
Woke up and about to invoke wait()
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at IncorrectSynchronization$1.run(HelloWorld.java:23)
at java.lang.Thread.run(Thread.java:748)
When the Thread t1 is sleeping, I modified the lock to false from another thread.
It then throws this IllegalMonitorStateException. It's still the same object, why would modifying the value cause IllegalMonitorStateException?
When I modify the lock to false from another thread inside a synchronized block, I no longer get that error. Can anyone explain the reason for what's happening under the hood?
public class HelloWorld{
public static void main( String args[] ) throws InterruptedException {
SampleTest.runExample();
}
}
class SampleTest{
Boolean flag = new Boolean(true);
public void example() throws InterruptedException {
Thread t0 = new Thread(new Runnable() {
public void run() {
synchronized (flag) {
try {
while (flag) {
System.out.println("First thread about to sleep");
Thread.sleep(2000);
System.out.println("Woke up and about to invoke wait()");
flag.wait();
System.out.println("wait() called");
}
} catch (InterruptedException ie) {
}
}
}
});
Thread t1 = new Thread(new Runnable() {
public void run() {
System.out.println("thread 1 run");
flag = false;
}
});
t0.start();
Thread.sleep(200);
t1.start();
t0.join();
t1.join();
}
public static void runExample() throws InterruptedException {
SampleTest test = new SampleTest();
test.example();
}
}
The problem is with this line:
flag = false;
This changes the reference of the flag Boolean variable, from the original Boolean object (which is created by the deprecated constructor which should not be used) to the pre-created Boolean.FALSE instance (due to autoboxing). By the time the first thread calls flag.wait(), the object is no longer the same as the one it used to synchronize, hence the IllegalMonitorStateException.
In this scenario, it's much better to use an AtomicBoolean and mutate its value in the other thread:
AtomicBoolean flag = new AtomicBoolean(true);
Now the second thread can update the value of the same object. It should also probably notify the first thread that is waiting on the object (like wait(), notify() also requires synchronizing on the object on which it is invoked):
Thread t1 = new Thread(new Runnable() {
public void run() {
synchronized(flag) {
System.out.println("thread 1 run");
flag.set(false);
flag.notify();
}
}
});

How locking works in java

I am writing a program to test how a thread can keep waiting if another thread has acquired lock on same object but after looking at output I am not sure how locking works in java. Here is what i have written:
public class Locking {
synchronized void methodA() {
System.out.println("inside A , " + Thread.currentThread().getName());
}
public static void main(String[] args) throws InterruptedException {
new Locking().execute();
}
private void execute() throws InterruptedException {
Thread t1 = new Thread(new MyThread());
t1.setName("t1");
Thread t2 = new Thread(new MyThread());
t2.setName("t2");
t1.start();
Thread.sleep(5000);
t2.start();
}
class MyThread implements Runnable {
#Override
public void run() {
while (true) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
methodA();
}
}
}
}
I expected thread t2 to be waiting forever and program will print only
inside A , t1
but when i run the program , I get following output:
inside A , t1
inside A , t2
Can anyone explain what is going on here?
I am writing a program to test how a thread can keep waiting if
another thread has acquired lock on same object
The single lock is here :
synchronized void methodA() {
System.out.println("inside A , " + Thread.currentThread().getName());
}
It takes the locks on the current instance but no statement in your code locks in a way where a thread could wait forever the lock.
Look at my comments :
#Override
public void run() {
while (true) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// the lock is set here
methodA();
// and that is released here
}
}
Make the synchronized method never releases the lock and only one of the thread will be able to enter in :
synchronized void methodA() {
while (true) {
System.out.println("inside A , " + Thread.currentThread()
.getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// handle it
}
}
}
prints :
inside A , t1
inside A , t1
inside A , t1
...
Her are some other examples to play with threads.
Replace sleep() by wait() and the current thread will release the lock :
synchronized void methodA() {
while (true) {
System.out.println("inside A , " + Thread.currentThread()
.getName());
try {
wait();
} catch (InterruptedException e) {
// handle it
}
}
}
prints :
inside A , t1
inside A , t2
Use notify() (to notify a waiting thread) and wait() (to make the current thread wait and release the lock if it has) to make threads collaborating between them :
synchronized void methodA() {
while (true) {
notify();
System.out.println("inside A , " + Thread.currentThread()
.getName());
try {
wait();
} catch (InterruptedException e) {
// handle it
}
}
}
prints :
inside A , t1
inside A , t2
inside A , t1
inside A , t2
...
That is intended situation.
Your t1 thread is waiting in another thread not main thread.
In your main thread(make threads and call start()), just waiting 5 seconds and start thread2
your synchronized method is synchronizing only when thread 1 calls that method not forever.
After thread1 calls synchorinized method and return, thread1 is stopping 5seconds.
In that time, thread2 can use that method.
The keyword synchronized infront of a method means, that the method cannot be called by two threads at the same time.
As soon as the method is called by a thread, other threads trying to call that same method are blocked until the first thread returns from that method. Afterwards the other threads calling the same method can automatically continue with the call (one at a time).
You implicit lock with synchronized is working for a short period - that is the println after that the lock is released. Both of your threads are racing to obtain the lock there.
Change your code to this and you will see the behavior you want
class MyThread implements Runnable {
#Override
public void run() {
methodA();
}
}
synchronized void methodA() {
while(true)
System.out.println("inside A , " + Thread.currentThread().getName());
}

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.

Implementing deadlock condition

I am trying to implementing deadlock condition but somehow I am not able to get it working. Both the threads Thread1 and Thread2 are entering in the run function but only one of them enters in Sub/Sum depending on who entered run first. Example : if Thread2 entered run first the it will call sub() and Thread1 never calls sum(). I have also added sleep time so that Thread2 sleeps before calling sum() and Thread1 gets enough time to enter Sum() but Thread1 never enters.
public class ExploringThreads {
public static void main(String[] args) {
// TODO Auto-generated method stub
threadexample a1 = new threadexample();
Thread t1 = new Thread(a1, "Thread1");
Thread t2 = new Thread(a1,"Thread2");
t1.start();
t2.start();
}
}
class threadexample implements Runnable{
public int a = 10;
public void run(){
if(Thread.currentThread().getName().equals("Thread1"))
sum();
else if(Thread.currentThread().getName().equals("Thread2"))
sub();
}
public synchronized void sum()
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"In Sum");
sub();
}
public synchronized void sub()
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"In Sub");
sum();
}
}
If you really want to create an artificial dead lock, try this:
Thread1 and Thread2 are two threads that want to access the same file.
Thread1 starts, asks for a lock on File1.docx and sleeps for 2 minutes.
Thread2 starts, and makes an exclusive lock on File2.docx and now wants to access File1.docx.
Thread1 wakes up and now wants to access File2.docx which is held by Thread2
Now, this is a circular wait condition
Simple ? =)
This is not how you get a deadlock. Actually this code seems pretty safe :-) Only one thread enters sum/sub at a time because you are using synchronized which synchronizes on "this". There is only one "this" so both threads try to acquire the same lock.
Deadlock occurs, for instance, when Thread1 has one lock, Thread2 has second lock and then Thread1 would like to acquire Thread2's lock while still holding it's lock and Thread2 would like to acquire Thread1's lock while still holding it's lock.
What you could do is:
a) add 2 objects for locking in "threadexample" class (btw classes by convention should start with uppercase):
private final Object sumLock = new Object();
private final Object subLock = new Object();
b) drop the "synchronized" keyword in both sum/sub methods and instead use the synchronized() {} block in each of them. Sum would be synchronized(sumLock) { /* sum's body goes here / } and sub would be synchronized(subLock) { / sub's body goes here */}.
In this case Thread1 would go into sum(), acquire the sumLock and wait. Thread2 would go into sub(), acquire the subLock() and wait. Thread1 would wake up, go into sub() and try to acquire subLock but it's being held by Thread2 so it wait's until Thread2 releases it. In that time Thread2 wakes up, goes into sum() and tries to acquire sumLock which is held by Thread1 so Thread2 waits for Thread1 to release it.
Neither thread will go forward as each one of them is waiting for the other - you have a deadlock.
#Edit: yes you have only 1 instance of "threadexample" and both Thread1 and Thread2 are fighting for the lock but when one of them acquires the lock it will release it after executing sum/sub or sub/sum. For instance let's say Thread1 is first and starts executing sum(). It has the lock. In that case Thread2 will not go into sub() as it is protected by the same lock as Thread1. Thread1 will do sum(), then sub() and then it will release the lock --> Thread2 will go into sub() etc.
This is a working example of 'Deadlock in Action'. Basically what you need to do (and how that usually happens in real world) is that object are locked in opposite order: a first, b second in one thread and b first, a second in another:
package stackoverflow;
public class Deadlock {
final static String a = new String("A");
final static String b = new String("B");
public static void main(String[] args) {
final Thread abLock = new Thread() {
#Override
public void run() {
lock(a, b);
}
};
final Thread baLock = new Thread() {
#Override
public void run() {
lock(b, a);
}
};
abLock.start();
baLock.start();
}
static void lock(String first, String second) {
synchronized (first) {
System.out.println(first);
sleep();
synchronized (second) {
System.out.println(second);
}
}
}
static void sleep() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}

Two threads entering synchronized methods of runnable

Here is a code i am having problem with --
public class WaitTest {
public static void main(String[] args) {
Runner rr = new Runner();
Thread t1 = new Thread(rr,"T1");
Thread t2 = new Thread(rr,"T2");
t1.start();
t2.start();
}
}
class Runner implements Runnable{
int i=0;
public void run(){
try{
if(Thread.currentThread().getName().equals("T1")){
bMethod();
aMethod();
}
else{
aMethod();
bMethod();
}
}catch(Exception e){}
}
public synchronized void aMethod() throws Exception{
System.out.println("i="+i+",Now going to Wait in aMethod "+Thread.currentThread().getName());
Thread.currentThread().wait();
System.out.println("Exiting aMethod "+Thread.currentThread().getName());
}
public synchronized void bMethod() throws Exception{
System.out.println("i="+i+",Now going to Wait bMethod "+Thread.currentThread().getName());
i=5;
notifyAll();
System.out.println("Exiting bMethod "+Thread.currentThread().getName());
}
}
The output is :
i=0,Now going to Wait bMethod T1
Exiting bMethod T1
i=5,Now going to Wait in aMethod T1
i=5,Now going to Wait in aMethod T2
My question is :
Why T2 enters in aMethod while T1 is waiting inside? and Why T2 prints
i=5 in aMethod.
When you execute wait, your thread releases the lock and enters the wait state. At this time the other thread is allowed to enter the method. You are using a single instance of Runnable so when one thread sets it to 5, that's what the other thread reads.
1. wait will immediately release the lock, and handover the lock to the other thread.
2. notify will release the lock only when the closing parenthesis of the synchronized block
is reached.
3. As there is only one instance of Runnable here, its after the i = 5, and when the synchronized block ends..then the lock is released.
This code is not doing the wait-notify pattern. The Thread.currentThread().wait() call throws an IllegalMonitorStateException, which is caught and ignored by the run method. Both T1 and T2 throws this exception, and hence you do not see the line Exiting aMethod printed.
The notify call in bMethod is wasted, because no thread ever waits on the intrinsic lock of the rr Runnable.

Categories