The code given here on https://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html gives synchronisation of bow and bower with lock objects , so that it can avoid deadlock.
here is the code
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.Random;
public class Safelock {
static class Friend {
private final String name;
private final Lock lock = new ReentrantLock();
public Friend(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public boolean impendingBow(Friend bower) {
Boolean myLock = false;
Boolean yourLock = false;
try {
myLock = lock.tryLock();
yourLock = bower.lock.tryLock();
} finally {
if (! (myLock && yourLock)) {
if (myLock) {
lock.unlock();
}
if (yourLock) {
bower.lock.unlock();
}
}
}
return myLock && yourLock;
}
public void bow(Friend bower) {
if (impendingBow(bower)) {
try {
System.out.format("%s: %s has"
+ " bowed to me!%n",
this.name, bower.getName());
bower.bowBack(this);
} finally {
lock.unlock();
bower.lock.unlock();
}
} else {
System.out.format("%s: %s started"
+ " to bow to me, but saw that"
+ " I was already bowing to"
+ " him.%n",
this.name, bower.getName());
}
}
public void bowBack(Friend bower) {
System.out.format("%s: %s has" +
" bowed back to me!%n",
this.name, bower.getName());
}
}
static class BowLoop implements Runnable {
private Friend bower;
private Friend bowee;
public BowLoop(Friend bower, Friend bowee) {
this.bower = bower;
this.bowee = bowee;
}
public void run() {
Random random = new Random();
for (;;) {
try {
Thread.sleep(random.nextInt(10));
} catch (InterruptedException e) {}
bowee.bow(bower);
}
}
}
public static void main(String[] args) {
final Friend alphonse =
new Friend("Alphonse");
final Friend gaston =
new Friend("Gaston");
new Thread(new BowLoop(alphonse, gaston)).start();
new Thread(new BowLoop(gaston, alphonse)).start();
}
}
My Question is - supposedly thread 1 - alphanso thread and thread 2 - gaston thread executes at same pace all the time. So they will call impendingBow() together. Both of them tries to acquire lock of itself and another object and if any of the lock is not available then they release the acquired lock if any.
Now if both threads are executing lines in same rate , So alphanso thread will be able to get lock of itself and so will gaston but both will fail to get lock of other as they have been acquired by themselves .
Now according to code both of them will free their own lock ( as they could not get other's lock.) and return false from impendingBow() and both will print
else {
System.out.format("%s: %s started"
+ " to bow to me, but saw that"
+ " I was already bowing to"
+ " him.%n",
this.name, bower.getName());
}
and then again the same thing.
Wont this process run indefinitely with no one bowing to each other ever?
Class BowLoop has infinite loop with a random delay (Thread.sleep(random.nextInt(10));) which prevents scenario that you described. It is a common practice to use random delay before reattempting to get locks after release in case of "collisions".
I wanted to intentionally do/test java thread deadlock state so I made a following sample code:
public class TestDeadLock extends Thread{
private Integer a=new Integer(9);
public void run(){
if(Thread.currentThread().getName().equals("t1")){
XXXX();
}
else{
ZZZZ();
}
}
public void XXXX(){
System.out.println("inside XXXX");
synchronized(a){
a++;
ZZZZ();
}
System.out.println("xxxxxxxxxxxxxxxxxxx");
//ZZZZ();
}
public synchronized void ZZZZ(){
System.out.println("inside ZZZZ");
synchronized(a){
a--;
XXXX();
}
System.out.println("zzzzzzzzzzzzzzzzzzzzz");
}
public static void main(String[] args) throws InterruptedException {
TestDeadLock tdl=new TestDeadLock();
Thread t1=new Thread(tdl);
Thread t2=new Thread(tdl);
t1.setName("t1");
t2.setName("t2");
t1.start();
t2.start();
Thread.sleep(1000);
System.out.println("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="+tdl.a);
}
}
The output came out to be like :
inside XXXX
inside ZZZZ
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=10
output is NOT exiting.
I wanted to know, was it due to threads reached Dead Lock state? Is it a right example to experience Dead Lock. Suggest or correct me if I am wrong.
No, you are not experiencing a dead lock. You are encountering a StackOverflowError because you are running into an infinite loop.
Note that your method
public synchronized void ZZZZ() {
System.out.println("inside ZZZZ");
XXXX(); // run-time exception
}
is equivalent to
public void ZZZZ() {
synchronized(this) {
System.out.println("inside ZZZZ");
XXXX(); // run-time exception
}
}
You are not causing a dead lock because you are working on two different instances.
Thread 1 locks t1, thread 2 locks t2.
Your ZZZZ() method contains a call to XXXX() method and vice-versa.
Thus, you have created a never-ending chain of calls that goes: ZZZZ() -> XXXX() -> ZZZZ() -> XXXX() -> etc.
Eventually, your stack will grow too large from all the nested method calls that get pushed onto the stack. Hence, the exceptions that you are getting.
Try this example:
public class TestThread {
public static Object Lock1 = new Object();
public static Object Lock2 = new Object();
public static void main(String args[]) {
ThreadDemo1 T1 = new ThreadDemo1();
ThreadDemo2 T2 = new ThreadDemo2();
T1.start();
T2.start();
}
private static class ThreadDemo1 extends Thread {
public void run() {
synchronized (Lock1) {
System.out.println("Thread 1: Holding lock 1...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 1: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 1: Holding lock 1 & 2...");
}
}
}
}
private static class ThreadDemo2 extends Thread {
public void run() {
synchronized (Lock2) {
System.out.println("Thread 2: Holding lock 2...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 2: Waiting for lock 1...");
synchronized (Lock1) {
System.out.println("Thread 2: Holding lock 1 & 2...");
}
}
}
}
}
This accurately shows threads reaching deadlock.
Here is the solution:
public class TestThread {
public static Object Lock1 = new Object();
public static Object Lock2 = new Object();
public static void main(String args[]) {
ThreadDemo1 T1 = new ThreadDemo1();
ThreadDemo2 T2 = new ThreadDemo2();
T1.start();
T2.start();
}
private static class ThreadDemo1 extends Thread {
public void run() {
synchronized (Lock1) {
System.out.println("Thread 1: Holding lock 1...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 1: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 1: Holding lock 1 & 2...");
}
}
}
}
private static class ThreadDemo2 extends Thread {
public void run() {
synchronized (Lock1) {
System.out.println("Thread 2: Holding lock 1...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 2: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 2: Holding lock 1 & 2...");
}
}
}
}
}
Source: http://www.tutorialspoint.com/java/java_thread_deadlock.htm
Example given by Jase Pellerin is a good example of dead lock but it has one mistake (Sorry Jase Pellerin , i am sure you did it unintetionally) . Here, both methods are trying to get hold of Lock1 first and then Lock2. I think it should be other way around.
Thread1{
synchronized (Lock1) {
synchronized (Lock2) {}
}
}
Thread2{
synchronized (Lock2) {
synchronized (Lock1) {}
}
}
public class SimpleDeadlock implements Runnable{
static SimpleDeadlock sc1=null;
static SimpleDeadlock sc2=null;
void access(SimpleDeadlock sc){
if(Thread.currentThread().getName().equals("Thread1"))
threadMethod1(sc);
if(Thread.currentThread().getName().equals("Thread2"))
threadMethod2(sc);
}
public synchronized void threadMethod1(SimpleDeadlock sc) {
System.out.println(Thread.currentThread().getName()+": threadMethod1");
try{
Thread.sleep(1000);
}
catch(InterruptedException ie){}
sc.deadlock();
}
public synchronized void threadMethod2(SimpleDeadlock sc) {
System.out.println(Thread.currentThread().getName()+": threadMethod2");
try{
Thread.sleep(1000);
}
catch(InterruptedException ie){}
sc.deadlock();
}
synchronized void deadlock() {
System.out.println("In deadlock...");
}
public void run(){
if(Thread.currentThread().getName().equals("Thread1"))
access(sc1);
if(Thread.currentThread().getName().equals("Thread2"))
access(sc2);
}
public static void main(String[] args) throws InterruptedException{
sc1=new SimpleDeadlock();
sc2=new SimpleDeadlock();
Thread thread1=new Thread(sc1);
Thread thread2=new Thread(sc2);
thread1.setName("Thread1");
thread2.setName("Thread2");
thread1.start();
thread2.start();
Thread.sleep(10000);
System.out.println(thread1.getName()+":"+thread1.getState());
System.out.println(thread2.getName()+":"+thread2.getState());
}
}
When I am interchanging the object in access method which is in run method this example occurs in deadlock as Thread1 waits for Thread2 to finish and vice versa.
But when it is in given state it doesn't go in deadlock. WHY? When thread1 calls synchronized method threadMethod1(), the object sc1 is locked. Then how in that method the locked object sc1 calls another synchronized method.
Locks in Java are reentrant. If a thread has already acquired a lock and tries to acquire it again, there won't be any problem.
I'm trying to learn the basics of java concurrency, I start with oracle java tutorial until http://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html, I just add some line to the code example,but when I run the code, the main method never return.
I know that both of alphonseThread and gastonThread are deadlocked by each ether, but why can't interrupt them from the main Thread?
public class DeadLock {
static class Freind {
private final String name;
public Freind(String name_) {
this.name = name_;
}
public String getName() {
return this.name;
}
public synchronized void bow(Freind bower) throws InterruptedException {
System.out.format("%s : %s " + "has bowed to me!%n",
this.name, bower.getName());
Thread.sleep(2000);
bower.bowBack(this);
}
public synchronized void bowBack(Freind bower) {
System.out.format("%s : %s " + "has bowed back to me!%n",
this.name, bower.getName());
}
}
#SuppressWarnings("SleepWhileInLoop")
public static void main(String[] args) throws InterruptedException {
// wait for 4 seconds before send a interuption signal
int patient = 4000;
int waitingUnit = 1000;
long start;
final Freind alphonse = new Freind("Alphonse");
final Freind gaston = new Freind("Gaston");
// the first thread
Thread alphonseThread = new Thread(new Runnable() {
#Override
public void run() {
try {
alphonse.bow(gaston);
} catch (InterruptedException ex) {
System.out.println("Alphnso have been killed");
}
}
});
// the second thread
Thread gastonThread = new Thread(new Runnable() {
#Override
public void run() {
try {
gaston.bow(alphonse);
} catch (InterruptedException ex) {
System.out.println("Gaston have been killed ");
}
}
});
// start the tow threads
start = System.currentTimeMillis();
alphonseThread.start();
gastonThread.start();
while (alphonseThread.isAlive() || gastonThread.isAlive()) {
if (((System.currentTimeMillis() - start) < patient)
&& (alphonseThread.isAlive() || gastonThread.isAlive())) {
System.out.println(System.currentTimeMillis() - start);
System.out.println("still waiting !!");
Thread.sleep(waitingUnit);
} else {
if (alphonseThread.isAlive()) {
alphonseThread.interrupt();
alphonseThread.join();
}
if (gastonThread.isAlive()) {
gastonThread.interrupt();
gastonThread.join();
}
}
}
System.out.println("finnaly I kill all of them");
}
}
but why can't interrupt them from the main Thread?
You can interrupt from the main thread (or anywhere). Just call Thread.interrupt() on the thread you want to interrupt.
The problem is that interrupt won't unblock a thread that is trying to acquire a Java primitive lock / mutex. In fact, I don't think there is anything that will safely unblock threads that are deadlocked on primitive locks.
If you want your application to be able to recover from deadlocks involving object locks, then you should probably be using Lock objects, and the Lock.lockInterruptibly() method ... which will unblock when the thread is interrupted.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I recently got this questions asked in an interview.
I answered that deadlock occurs if the interleaving goes wrong, but the interviewer insisted that a program that will always go into deadlock regardless of interleaving can be written .
Can we write such a program ? Can you point me to some example program like that ?
UPDATE: This question was the subject of my blog in January 2013. Thanks for the great question!
How can we write a program that will always go into deadlock no matter how the threads are scheduled?
Here's an example in C#. Note that the program appears to contain no locks and no shared data. It has only a single local variable and three statements, and yet it deadlocks with 100% certainty. One would be hard-pressed to come up with a simpler program that deadlocks with certainty.
Exercise to the reader #1: explain how this deadlocks. (An answer is in the comments.)
Exercise to the reader #2: demonstrate the same deadlock in Java. (An answer is here: https://stackoverflow.com/a/9286697/88656)
class MyClass
{
static MyClass()
{
// Let's run the initialization on another thread!
var thread = new System.Threading.Thread(Initialize);
thread.Start();
thread.Join();
}
static void Initialize()
{ /* TODO: Add initialization code */ }
static void Main()
{ }
}
The latch here ensure that both locks are held when each thread tries to lock the other:
import java.util.concurrent.CountDownLatch;
public class Locker extends Thread {
private final CountDownLatch latch;
private final Object obj1;
private final Object obj2;
Locker(Object obj1, Object obj2, CountDownLatch latch) {
this.obj1 = obj1;
this.obj2 = obj2;
this.latch = latch;
}
#Override
public void run() {
synchronized (obj1) {
latch.countDown();
try {
latch.await();
} catch (InterruptedException e) {
throw new RuntimeException();
}
synchronized (obj2) {
System.out.println("Thread finished");
}
}
}
public static void main(String[] args) {
final Object obj1 = new Object();
final Object obj2 = new Object();
final CountDownLatch latch = new CountDownLatch(2);
new Locker(obj1, obj2, latch).start();
new Locker(obj2, obj1, latch).start();
}
}
Interesting to run jconsole, which will correctly show you the deadlock in the Threads tab.
Deadlock happens when threads (or whatever your platform calls its execution units) acquire resources, where each resource can only be held by one thread at a time, and holds on to those resources in a such a way that the holds cannot be preempted, and there exists some "circular" relationship between the threads such that each thread in the deadlock is waiting to acquire some resource held by another thread.
So, an easy way to avoid deadlock is to give some total ordering to resources and impose a rule that resources are only ever acquired by threads in order. Conversely, a deadlock can be intentionally created by running threads that acquire resources, but do not acquire them in order. For example:
Two threads, two locks. The first thread runs a loop that attempts to acquire the locks in a certain order, the second thread runs a loop that attempts to acquire the locks in the opposite order. Each thread releases both locks after successfully acquiring the locks.
public class HighlyLikelyDeadlock {
static class Locker implements Runnable {
private Object first, second;
Locker(Object first, Object second) {
this.first = first;
this.second = second;
}
#Override
public void run() {
while (true) {
synchronized (first) {
synchronized (second) {
System.out.println(Thread.currentThread().getName());
}
}
}
}
}
public static void main(final String... args) {
Object lock1 = new Object(), lock2 = new Object();
new Thread(new Locker(lock1, lock2), "Thread 1").start();
new Thread(new Locker(lock2, lock1), "Thread 2").start();
}
}
Now, there have been a few comments in this question that point out the difference between the likelihood and the certainty of deadlock. In some sense, the distinction is an academic issue. From a practical standpoint, I'd certainly like to see a running system that doesn't deadlock with the code I've written above :)
However, interview questions can be academic at times, and this SO question does have the word "surely" in the title, so what follows is a program that certainly deadlocks. Two Locker objects are created, each is given two locks and a CountDownLatch used to synchronize between the threads. Each Locker locks the first lock then counts down the latch once. When both threads have acquired a lock and counted down the latch, they proceed past the latch barrier and attempt to acquire a second lock, but in each case the other thread already holds the desired lock. This situation results in a certain deadlock.
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class CertainDeadlock {
static class Locker implements Runnable {
private CountDownLatch latch;
private Lock first, second;
Locker(CountDownLatch latch, Lock first, Lock second) {
this.latch = latch;
this.first = first;
this.second = second;
}
#Override
public void run() {
String threadName = Thread.currentThread().getName();
try {
first.lock();
latch.countDown();
System.out.println(threadName + ": locked first lock");
latch.await();
System.out.println(threadName + ": attempting to lock second lock");
second.lock();
System.out.println(threadName + ": never reached");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public static void main(final String... args) {
CountDownLatch latch = new CountDownLatch(2);
Lock lock1 = new ReentrantLock(), lock2 = new ReentrantLock();
new Thread(new Locker(latch, lock1, lock2), "Thread 1").start();
new Thread(new Locker(latch, lock2, lock1), "Thread 2").start();
}
}
Here is a Java example by following Eric Lippert's one:
public class Lock implements Runnable {
static {
System.out.println("Getting ready to greet the world");
try {
Thread t = new Thread(new Lock());
t.start();
t.join();
} catch (InterruptedException ex) {
System.out.println("won't see me");
}
}
public static void main(String[] args) {
System.out.println("Hello World!");
}
public void run() {
Lock lock = new Lock();
}
}
Here is an Example from the documentation:
public class Deadlock {
static class Friend {
private final String name;
public Friend(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public synchronized void bow(Friend bower) {
System.out.format("%s: %s"
+ " has bowed to me!%n",
this.name, bower.getName());
bower.bowBack(this);
}
public synchronized void bowBack(Friend bower) {
System.out.format("%s: %s"
+ " has bowed back to me!%n",
this.name, bower.getName());
}
}
public static void main(String[] args) {
final Friend alphonse =
new Friend("Alphonse");
final Friend gaston =
new Friend("Gaston");
new Thread(new Runnable() {
public void run() { alphonse.bow(gaston); }
}).start();
new Thread(new Runnable() {
public void run() { gaston.bow(alphonse); }
}).start();
}
}
I've rewritten Yuriy Zubarev's Java version of the deadlock example posted by Eric Lippert: https://stackoverflow.com/a/9286697/2098232 to more closely resemble the C# version. If the Java's initialization block works similarily to C# static constructor and first acquires the lock we don't need another thread to also invoke the join method to get a deadlock, it only needs to invoke some static method from Lock class, like the original C# example. Resulting deadlock seems to confirm this.
public class Lock {
static {
System.out.println("Getting ready to greet the world");
try {
Thread t = new Thread(new Runnable(){
#Override
public void run() {
Lock.initialize();
}
});
t.start();
t.join();
} catch (InterruptedException ex) {
System.out.println("won't see me");
}
}
public static void main(String[] args) {
System.out.println("Hello World!");
}
public static void initialize(){
System.out.println("Initializing");
}
}
It's not a simplest interview task you can get: in my project, it paralysed a team's work for a whole day. It's very easy to make your program stop, but it's very hard to get it to the state where thread dump writes something like,
Found one Java-level deadlock:
=============================
"Thread-2":
waiting to lock monitor 7f91c5802b58 (object 7fb291380, a java.lang.String),
which is held by "Thread-1"
"Thread-1":
waiting to lock monitor 7f91c6075308 (object 7fb2914a0, a java.lang.String),
which is held by "Thread-2"
Java stack information for the threads listed above:
===================================================
"Thread-2":
at uk.ac.ebi.Deadlock.run(Deadlock.java:54)
- waiting to lock <7fb291380> (a java.lang.String)
- locked <7fb2914a0> (a java.lang.String)
- locked <7f32a0760> (a uk.ac.ebi.Deadlock)
at java.lang.Thread.run(Thread.java:680)
"Thread-1":
at uk.ac.ebi.Deadlock.run(Deadlock.java:54)
- waiting to lock <7fb2914a0> (a java.lang.String)
- locked <7fb291380> (a java.lang.String)
- locked <7f32a0580> (a uk.ac.ebi.Deadlock)
at java.lang.Thread.run(Thread.java:680)
So the goal would be to get a deadlock which JVM will consider a deadlock. Obviously, no solution like
synchronized (this) {
wait();
}
will work in that sense, even though they will indeed stop forever. Relying on a race condition is not a good idea, either, as during interview you usually want to show something provably working, not something which should work most of the time.
Now, the sleep() solution is okay in a sense it's hard to imagine a situation where it doesn't work, but not fair (we're in a fair sport, aren't we?). The solution by #artbristol (mine is the same, just different objects as monitors) is nice, but long and uses the new concurrency primitives to get the threads in the the right state, which is not that much fun:
public class Deadlock implements Runnable {
private final Object a;
private final Object b;
private final static CountDownLatch latch = new CountDownLatch(2);
public Deadlock(Object a, Object b) {
this.a = a;
this.b = b;
}
public synchronized static void main(String[] args) throws InterruptedException {
new Thread(new Deadlock("a", "b")).start();
new Thread(new Deadlock("b", "a")).start();
}
#Override
public void run() {
synchronized (a) {
latch.countDown();
try {
latch.await();
} catch (InterruptedException ignored) {
}
synchronized (b) {
}
}
}
}
I do recall that the synchronized-only solution fits 11..13 lines of code (excluding comments and imports), but have yet to recall the actual trick. Will update if I do.
Update: here's an ugly solution on synchronized:
public class Deadlock implements Runnable {
public synchronized static void main(String[] args) throws InterruptedException {
synchronized ("a") {
new Thread(new Deadlock()).start();
"a".wait();
}
synchronized ("") {
}
}
#Override
public void run() {
synchronized ("") {
synchronized ("a") {
"a".notifyAll();
}
synchronized (Deadlock.class) {
}
}
}
}
Note we replace a latch with an object monitor (using "a" as an object).
This C# version, I guess java should be pretty similar.
static void Main(string[] args)
{
var mainThread = Thread.CurrentThread;
mainThread.Join();
Console.WriteLine("Press Any key");
Console.ReadKey();
}
import java.util.concurrent.CountDownLatch;
public class SO8880286 {
public static class BadRunnable implements Runnable {
private CountDownLatch latch;
public BadRunnable(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
System.out.println("Thread " + Thread.currentThread().getId() + " starting");
synchronized (BadRunnable.class) {
System.out.println("Thread " + Thread.currentThread().getId() + " acquired the monitor on BadRunnable.class");
latch.countDown();
while (true) {
try {
latch.await();
} catch (InterruptedException ex) {
continue;
}
break;
}
}
System.out.println("Thread " + Thread.currentThread().getId() + " released the monitor on BadRunnable.class");
System.out.println("Thread " + Thread.currentThread().getId() + " ending");
}
}
public static void main(String[] args) {
Thread[] threads = new Thread[2];
CountDownLatch latch = new CountDownLatch(threads.length);
for (int i = 0; i < threads.length; ++i) {
threads[i] = new Thread(new BadRunnable(latch));
threads[i].start();
}
}
}
The program always deadlocks because each thread is waiting at the barrier for the other threads, but in order to await the barrier, the thread must be holding the monitor on BadRunnable.class.
There's an example in Java here
http://baddotrobot.com/blog/2009/12/24/deadlock/
Where a kidnapper gets into a deadlock when he refuses to give up the victim until he gets the cash but the negotiator refuses to give up the cash until he gets the victim.
A simple search gave me the following code:
public class Deadlock {
static class Friend {
private final String name;
public Friend(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public synchronized void bow(Friend bower) {
System.out.format("%s: %s"
+ " has bowed to me!%n",
this.name, bower.getName());
bower.bowBack(this);
}
public synchronized void bowBack(Friend bower) {
System.out.format("%s: %s"
+ " has bowed back to me!%n",
this.name, bower.getName());
}
}
public static void main(String[] args) {
final Friend alphonse =
new Friend("Alphonse");
final Friend gaston =
new Friend("Gaston");
new Thread(new Runnable() {
public void run() { alphonse.bow(gaston); }
}).start();
new Thread(new Runnable() {
public void run() { gaston.bow(alphonse); }
}).start();
}
}
Source: Deadlock
Here's sample where one thread holding lock starts another thread which wants the same lock and then starter waits until started finishes... forever:
class OuterTask implements Runnable {
private final Object lock;
public OuterTask(Object lock) {
this.lock = lock;
}
public void run() {
System.out.println("Outer launched");
System.out.println("Obtaining lock");
synchronized (lock) {
Thread inner = new Thread(new InnerTask(lock), "inner");
inner.start();
try {
inner.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class InnerTask implements Runnable {
private final Object lock;
public InnerTask(Object lock) {
this.lock = lock;
}
public void run() {
System.out.println("Inner launched");
System.out.println("Obtaining lock");
synchronized (lock) {
System.out.println("Obtained");
}
}
}
class Sample {
public static void main(String[] args) throws InterruptedException {
final Object outerLock = new Object();
OuterTask outerTask = new OuterTask(outerLock);
Thread outer = new Thread(outerTask, "outer");
outer.start();
outer.join();
}
}
Here is an example:
two threads are running , each one waiting for other to release lock
public class ThreadClass extends Thread{
String obj1,obj2;
ThreadClass(String obj1,String obj2){
this.obj1=obj1;
this.obj2=obj2;
start();
}
public void run(){
synchronized (obj1) {
System.out.println("lock on "+obj1+" acquired");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("waiting for "+obj2);
synchronized (obj2) {
System.out.println("lock on"+ obj2+" acquired");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Running this would lead to deadlock:
public class SureDeadlock {
public static void main(String[] args) {
String obj1= new String("obj1");
String obj2= new String("obj2");
new ThreadClass(obj1,obj2);
new ThreadClass(obj2,obj1);
}
}