I have two threads thread1(printing numbers) & thread2(printing alphabets).
My goal is to have the following output via syncronization:
1
a
2
b
3
c
4
d
5
e
class thread1 implements Runnable {
public void run() {
try {
for (int i = 1; i <= 5; i++) {
System.out.println("Is Thread1 holding lock of Testing.class?:"+Thread.holdsLock(Testing.class));
synchronized (Testing.class) {
System.out.println("Is Thread1 holding lock of Testing.class?:"+Thread.holdsLock(Testing.class));
try {
System.out.println(i);
Testing.class.notifyAll();
System.out.println("Thread1:Going to wait");
Testing.class.wait();
System.out.println("Thread1:Resuming from wait");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("Finsihed thread1");
} catch (Exception e) {
System.out.println(e);
}
}
}
class thread2 implements Runnable {
char[] alphabets = { 'a', 'b', 'c', 'd', 'e' };
public void run() {
try {
for (int i = 0; i < 5; i++) {
System.out.println("Is Thread2 holding lock of Testing.class?:"+Thread.holdsLock(Testing.class));
synchronized (Testing.class) {
try {
System.out.println("Is Thread2 holding lock of Testing.class?:"+Thread.holdsLock(Testing.class));
System.out.println("Thread2:Going to wait");
Testing.class.wait();
System.out.println("Thread2:Resuming from wait");
System.out.println(alphabets[i]);
Testing.class.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} catch (Exception e) {
System.out.println(e);
}
}
}
public class Testing {
public static void main(String[] args) {
Testing w= new Testing();
thread1 t1 = new thread1();
thread2 t2 = new thread2();
Thread th1 = new Thread(t1, "");
Thread th2 = new Thread(t2, "");
try {
th1.start();
th2.start();
} catch (Exception e) {
System.out.println(e);
}
}
}
I am getting the output:
Is Thread1 holding lock of
Testing.class?:falseIs Thread1 holding lock of
Testing.class?:true1
Thread1:Going to wait
Is Thread2 holding lock of
Testing.class?:falseIs Thread2 holding lock of
Testing.class?:trueThread2:Going to wait
How did thread2 got hold the lock of Testing.class when it was already locked by thread1?. Also, Is there any other elegant way to achieve this sync?. Thanks in advance.
The basic problem you have is that you release the synchronized block allowing both threads to go through the loop at the same time. This means either thread can obtain the lock in any order.
AFAIK, The simplest solution is to use a flag.
The most elegant way to have this task done in sync is to have one thread. Threads are specificly designed to execute two tasks with as little dependence as possible between them.
BTW
If notifyAll() is called before wait() is called, the notify will be lost. wait() will wait forever.
You create a Testing object you discard (remove it).
You trap InterruptedException which you print and continue as if nothing happened (i.e. remove the nested catch)