Using lock order with implicit locks
package salpejava.Threads;
public class ProbableDeadLock {
public static void main(String[] args) {
final Resource resourceA = new Resource("RespurceA");
final Resource resourceB = new Resource("ResourceB");
// ReaderThread lock order A then B
Thread ReaderThread = new Thread(new Runnable() {
public void run() {
// Lock resource A
synchronized (resourceA) {
System.out.println(Thread.currentThread().getName()
+ " locked resource A");
// sleep retains lock
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
// try to get lock on resource B
synchronized (resourceB) {
System.out.println(Thread.currentThread().getName()
+ " locked resource B");
System.out.println("Reading A ...." +resourceA.getValue());
System.out.println("Reading B ...." +resourceB.getValue());
}
}
}
}, "ReaderThread");
// writerThread lock order B then A
Thread writerThread = new Thread(new Runnable() {
public void run() {
// take lock on B
synchronized (resourceB) {
System.out.println(Thread.currentThread().getName()
+ " locked resource B");
// sleep retains lock
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
// take lock on
synchronized (resourceA) {
System.out.println(Thread.currentThread().getName()
+ " locked resource A");
//updating A,B
resourceB.setValue("ModifiedB");
resourceB.setValue("ModifiedA");
}
}
}
}, "writerThread");
;
// Dead lock is can not be guaranteed because it depends on thread
// scheduler and underlaying OS
// It might change from OS to OS or machine to machine too..
ReaderThread.start();
writerThread.start();
}
private static class Resource {
private String value;
public Resource(String value) {
super();
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}
Using cyclic barrier and re-entrant lock (Following code is guaranteed to be work on any JVM to produce dead lock ..you can write me mail in other case ! )
package salpejava.Threads;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class GauranteedDeadLock {
final static CyclicBarrier barrier = new CyclicBarrier(6);
public static void main(String[] args) {
final Lock lock1 = new ReentrantLock();
final Lock lock2 = new ReentrantLock();
final Lock lock3 = new ReentrantLock();
final Resource resourceA = new Resource("RespurceA");
final Resource resourceB = new Resource("ResourceB");
final Resource resourceC = new Resource("ResourceC");
DeadLockThread[] threadArr = new DeadLockThread[6];
//create cyclic order of locks or objects to synchronize
threadArr[0] = new DeadLockThread("Thread-1", resourceA, resourceB);
threadArr[1] = new DeadLockThread("Thread-2", resourceB, resourceC);
threadArr[2] = new DeadLockThread("Thread-3", resourceC, resourceA);
threadArr[3] = new DeadLockThread("Thread-4", lock1, lock2);
threadArr[4] = new DeadLockThread("Thread-5", lock2, lock3);
threadArr[5] = new DeadLockThread("Thread-6", lock3, lock1);
for (int i = 0; i < 6; i++) {
threadArr[i].start();
}
}
static class DeadLockThread extends Thread {
String name = "";
Lock lock1;
Lock lock2;
boolean onLock = false;
Resource resource1;
Resource resource2;
public DeadLockThread(String name, Lock lock1, Lock lock2) {
super();
this.lock1 = lock1;
this.lock2 = lock2;
this.onLock = true;
this.name = name;
}
public DeadLockThread(String name, Resource resource1,
Resource resource2) {
super();
this.onLock = false;
this.resource1 = resource1;
this.resource2 = resource2;
this.name = name;
}
public void run() {
if (onLock) {
deadLockOnLocks();
} else {
deadLockOnObject();
}
};
public void deadLockOnLocks() {
//lock order will be different in each thread :)
lock1.lock();
try {
try {
barrier.await();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (BrokenBarrierException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// try to get lock on resource B
lock2.lock();
try {
barrier.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock2.unlock();
}
} finally {
lock1.unlock();
}
}
public void deadLockOnObject() {
//synchro order will be different in each thread :)
// Lock resource A
synchronized (resource1) {
System.out.println(Thread.currentThread().getName()
+ " locked resource 1");
// sleep retains lock
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
// try to get lock on resource B
synchronized (resource2) {
System.out.println(Thread.currentThread().getName()
+ " locked resource 2");
System.out.println("Reading 1 ...." + resource1.getValue());
System.out
.println("Reading 2 ...." + resource2.getValue());
}
}
}
}
private static class Resource {
private String value;
public Resource(String value) {
super();
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}