While passing SCJP6 exam simulator I found question like this:
class Clerk implements Runnable {
private Record A, B;
public Clerk(Record a, Record b) {
A = a;
B = b;
}
public void run() {
while(true) {
doStuff(A, B);
}
}
public synchronized void doStuff(Record a, Record b) {
synchronized(a) {
synchronized(b) {
a.add(1);
b.add(-1);
}}
}
}
then
Record a = new Record();
Record b = new Record();
new Thread(new Clerk(a, b)).start();
new Thread(new Clerk(a, b)).start();
Answer says that this code can cause deadlock, but I don't get it - how exactly is that possible? Can someone can help me figure that out?
Apart from the fact that it does not compile, there is no deadlock in that code. This code could definitely create a deadlock:
new Thread(new Clerk(a, b)).start();
new Thread(new Clerk(b, a)).start();
So if the question is: could the Clerk
class be the source of the deadlock? Then the answer is yes.
Short example that should deadlock fairly fast. If a and b are used like in the original question, the program runs fine.
public class Test1 {
public static void main(String[] args) {
Record a = new Record();
Record b = new Record();
new Thread(new Clerk(a, b)).start();
new Thread(new Clerk(b, a)).start();
}
static class Record {
}
static class Clerk implements Runnable {
private Record A, B;
public Clerk(Record a, Record b) {
A = a;
B = b;
}
public void run() {
while (true) {
System.out.println("in thread " + Thread.currentThread());
for (int i = 0; i < 10000; i++) {
doStuff(A, B);
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
}
}
public synchronized void doStuff(Record a, Record b) {
synchronized (a) {
synchronized (b) {
}
}
}
}
}