Does wait always need notify to work? - java

Till now I was aware that wait always need notify to work properly.But when tried the below code I am confused a bit about the working of wait and notify. I created three threads t1,t2,t3 and passed the runnable T1,T2 and T3 respectively.According to me when i started the three threads only t1 should print and t2 and t3 should go to waiting state and keeps on waiting as no one is notifying.
But the o/p is unpredictable for me.Can someone please expalin me a bit.Below are my classes.
package com.vikash.Threading;
class T1 implements Runnable {
private State state;
public T1(State state) {
this.state=state;
}
#Override
public void run() {
synchronized (state) {
while(state.getState()!=1) {
try {
state.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (state) {
System.out.println(Thread.currentThread().getName());
state.setState(2);
}
}
}
}
class T2 implements Runnable {
private State state;
public T2(State state) {
this.state=state;
}
#Override
public void run() {
synchronized (state) {
while(state.getState()!=2) {
try {
state.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (state) {
System.out.println(Thread.currentThread().getName());
state.setState(3);
}
}
}
}
class T3 implements Runnable {
private State state;
public T3(State state) {
this.state=state;
}
#Override
public void run() {
synchronized (state) {
while(state.getState()!=3) {
try {
state.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (state) {
System.out.println(Thread.currentThread().getName());
state.setState(1);
}
}
}
}
public class Sequence {
public static void main(String[] args) {
State state=new State();
Thread t1=new Thread(new T1(state),"First");
Thread t2=new Thread(new T2(state),"Second");
Thread t3=new Thread(new T3(state),"Third");
t1.start();
t2.start();
t3.start();
}
}
package com.vikash.Threading;
public class State {
private int state=1;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
}
As per comment I am modifying my question.The o/p sometimes I am getting First second and it does not terminate and sometimes First Second Third and terminate.

Your expectation is incorrect, it is possible for all your threads to print and end as your program is currently written (but this depends on random chance)
It depends on which thread grabs the monitor on state first using the synchronized block that they all have.
Consider this flow:
T1 enters the synchronized (state) block first. T2 and T3 are waiting to enter their synchronized (state) blocks.
T1 doesn't wait as state.getState() == 1, so instead
T1 prints the thread name and assigns 2 to state.state
T1 exits the synchronized block
Either T2 or T3 enter their synchronized (state) block, assume that it is T2 (which one enters first is undefined behaviour in Java, and likely this is random)
So T2 doesn't wait as state.getState() == 2
T2 prints the thread name and assigns 3 to state.state
T2 exits the synchronized block
T3 enters the synchronized block, doesn't wait, and prints the thread name
Program done.

Related

Java - Synchronized block not working

I have the following class
public class OddPrinter implements Runnable {
public void run() {
try {
for (int n = 0; n <= 10; n++) {
if((n%2) != 0)
System.out.println(" Odd Thread" + n);
Thread.sleep(1000);
}
System.out.println("Exiting Odd Thread");
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
And the main class which tries to have a synchronized access to the object of the above class
public class MultiThread {
public static void main(String[] args) {
Thread t1, t2;
OddPrinter first = new OddPrinter();
synchronized(first)
{
t1 = new Thread(first, "firstThread");
t1.start();
t2 = new Thread(first, "secondThread");
t2.start();
}
}
}
I am getting an output as follows
Odd Thread1
Odd Thread1
Odd Thread3
Odd Thread3
Odd Thread5
Odd Thread5
Odd Thread7
Odd Thread7
Odd Thread9
Odd Thread9
Exiting Odd Thread
Exiting Odd Thread
A synchronized block ensures
that a call to a method that is a member of object occurs only after the current thread has
successfully entered object’s monitor.
According to the above reference ( Java2 - The Complete Reference - Herbert Schildt), I am expecting an output where one thread waits for the other to finish the printing of the odd numbers. But that is not happening. What is the issue here?
A synchronized block ensures that a call to a method that is a member of object occurs only after the current thread has successfully entered object’s monitor.
No it doesn't. It ensures that a synchronized method that is an instance member of the class of the object occurs only after the current thread has exited the block, if invoked on the same object, and that another synchronized block on the same object doesn't execute until this block exits.
Several of those conditions don't apply to your code.
I am expecting an output where one thread waits for the other to finish the printing of the odd numbers.
Wait for thread t1 to complete before starting thread t2:
t1.start():
t1.join();
t2.start();
You only synchronized one access. The other threads don't synchronize on the object, so nothing is blocked. Even if they did and were, once both threads have started, the code block in main completes and the threads are free to run anyway.
Furthermore, the synchronization you used in main happens in advance of any other threads that might conflict, and the main thread doesn't need any shared state in the first place, so the synchronization there is useless.
Study the concepts "critical section", "memory barrier", and Java's "happens-before". Buy and study the book Java Concurrency in Practice, by Brian Goetz, et al.
synchronized lock should be put inside your runnable code, not your main method.
I think you can either put synchronize to your method
public class OddPrinter implements Runnable {
public synchronized void run() {
try {
for (int n = 0; n <= 10; n++) {
if((n%2) != 0)
System.out.println(" Odd Thread" + n);
Thread.sleep(1000);
}
System.out.println("Exiting Odd Thread");
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
Or, you can put it in your method like this
public class OddPrinter implements Runnable {
static Object lock;
public void run() {
synchronized (lock) {
try {
for (int n = 0; n <= 10; n++) {
if((n%2) != 0)
System.out.println(" Odd Thread" + n);
Thread.sleep(1000);
}
System.out.println("Exiting Odd Thread");
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
You need to change OddPrinter where you can put synchronized block and use a single lock to synchronized so at time one thread can enter to critical section.And remove the synchronized block from main method.
public class OddPrinter implements Runnable {
private Object lock;
public OddPrinter(Object lock) {
this.lock = lock;
}
public void run() {
synchronized (lock) {
for (int n = 0; n <= 10; n++) {
if ((n % 2) != 0)
System.out.println(" Odd Thread" + n);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Exiting Odd Thread");
}
}
}
public class MultiThread {
public static void main(String[] args) {
Thread t1, t2;
Object object=new Object();
t1 =new Thread(new OddPrinter(object),"firstThread");
t1.start();
t2 =new Thread(new OddPrinter(object),"secondThread");
t2.start();
}
}
This is definitely not the way synchronization should be implemented. In your implementation there is no monitor/locks or notify implementation since the lock acquired is soon out of scope of main thread's control.
It's completely wrong to do this way. In case you wanted to do something exclusive, the lock should be locked inside your thread -- not outside!.
public class MyThread implements Runnable {
private Object mutex;
public MyThread(Object sharedObject) {
this.mutex = sharedObject;
}
public void run() {
// Method 1 -- Class reference used as the mutex: locks and executes only one instance between the blocks
synchronized (MyThread.class) {
}
// Method 2 -- All the same instance of the object reference used as mutex receives a blocked interference, and only one thread is executed.
synchronized (mutex) {
}
}
// Method 3 - Only one synchronized method inside the class is executed at any given point in time.
private synchronized void produce() {
}
// Method 3 (Contd.) - Added in conjunction with produce() call
private synchronized void consume() {
}
}

Make even and odd threads to print numbers in natural order in Java

I know this question has been asked before, But I am unable to figure out why my solution is not working for me. I have two threads even and odd, one prints even numbers and other prints odd numbers. When I start the threads I want the output to be in natural order of numbers like 0 1 2 3..etc. This is my code:-
[updated]
public class ThreadCommunication {
public static void main(String... args) throws InterruptedException
{
final ThreadCommunication obj = new ThreadCommunication();
Thread even = new Thread(){
#Override
public void run()
{
for(int i=0;i<10;i=i+2){
synchronized(obj){
System.out.println(i);
try {
obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
};
Thread odd = new Thread(){
#Override
public void run()
{
for(int i=1;i<10;i=i+2){
synchronized(obj){
System.out.println(i);
obj.notify();
}
}
}
};
even.start();
odd.start();
}
}
when I run the above code, sometimes it prints the numbers in natural order as expected but sometimes it prints in some other order for ex:
0
1
3
5
7
9
2
What am I doing wrong here?
Edit:
volatile static boolean isAlreadyWaiting = false;
Thread even = new Thread() {
#Override
public void run() {
synchronized (obj) {
for (int i = 0; i < 10; i = i + 2) {
System.out.println(i);
try {
if (!isAlreadyWaiting) {
isAlreadyWaiting = true;
obj.wait();
}
obj.notify();
isAlreadyWaiting=false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Thread odd = new Thread() {
#Override
public void run() {
synchronized (obj) {
for (int i = 1; i < 10; i = i + 2) {
System.out.println(i);
try {
if(isAlreadyWaiting){
obj.notify();
isAlreadyWaiting = false;
}
if (!isAlreadyWaiting) {
isAlreadyWaiting = true;
obj.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Check documentation
public class IllegalMonitorStateException extends RuntimeException
Thrown to indicate that a thread has attempted to wait on an object's
monitor or to notify other threads waiting on an object's monitor
without owning the specified monitor.
Monitor is owned by obj
So you should call
obj.wait();
and
obj.notify();
For more info on Ownership
This methods (wait or notify) should only be called by a thread that
is the owner of this object's monitor. A thread becomes the owner of
the object's monitor in one of three ways:
By executing a synchronized instance method of that object.
By executing the body of a synchronized statement that synchronizes
on the object.
For objects of type Class, by executing a synchronized static method
of that class.
Only one thread at a time can own an object's monitor.
#Pragnani Kinnera is right about the exception you're seeing. But if you want to alternate between even and odd, you'll need to move your second synchronized block into the loop. Otherwise, the notifying thread will hold the lock exclusively until the loop completes. (As opposed to the first thread, which yields its lock on each round.)
Thread odd = new Thread(){
#Override
public void run()
{
for(int i=1;i<10;i=i+2){
synchronized(obj){
System.out.println(i);
notify();
}
}
}
};
The first thread, however, should have the loop inside the synchronized block. If both threads release the lock, they both have an equal chance at reacquiring it. But if the first loop is inside the synchronized block, the second thread won't be able to reenter until the first has completed a full round and is waiting once again.
EDIT: This still won't work correctly, because there is no guarantee that the first thread won't reacquire the lock before the second thread does, per this quote from the documentation:
The awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object.
You'll probably want to wake and notify from both threads to ensure they're in sync.
Here is your solution:
public class ThreadCommunication {
public static void main(String args[]) throws InterruptedException
{
final ThreadCommunication obj = new ThreadCommunication();
Thread even = new Thread("Even Thread"){
#Override
public void run()
{
for(int i=0;i<10;i=i+2){
System.out.println(i);
synchronized(obj){
obj.notify();
}
synchronized(obj){
try {
obj.wait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Thread odd = new Thread(){
#Override
public void run()
{
for(int i=1;i<10;i=i+2){
try {
synchronized(obj){
obj.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
synchronized(obj){
obj.notifyAll();
}
}
}
};
even.start();
odd.start();
}
}
As explained by #shmosel, your synchronized block should only contain code that need to be synchronized.

is this a thread deadlock

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) {}
}
}

interrupt one thread inside another thread's run method in Java

I was reading this post and the suggestions given to interrupt one thread from another is
" " " Here are a couple of approaches that should work, if implemented correctly.
You could have both threads regularly check some common flag variable (e.g. call it stopNow), and arrange that both threads set it when they finish. (The flag variable needs to be volatile ... or properly synchronized.)
You could have both threads regularly call the Thread.isInterrupted() method to see if it has been interrupted. Then each thread needs to call Thread.interrupt() on the other one when it finishes." " "
I do not understand how the second approach is possible that is using Thread.isInterrupted().
That is, how can Thread-1 call Thread.interrupt() on Thread-2.
Consider this example, in the main method I start two threads t1 and t2. I want t1 to stop t2 after reaching certain condition. how can I achieve this?
class Thread1 extends Thread {
public void run(){
while (!isDone){
// do something
}
} //now interrupt Thread-2
}
class Thread2 extends Thread {
public void run(){
try {
while(!Thread.isInterupted()){
//do something;
}
catch (InterruptedExecption e){
//do something
}
}
}
public class test {
public static void main(String[] args){
try {
Thread1 t1 = new Thread1();
Thread2 t2 = new Thread2();
t1.start();
t2.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The context of this is that you are trying to implement your scheme using thread interrupts.
In order for that to happen, the t1 object needs the reference to the t2 thread object, and then it simply calls t2.interrupt().
There are a variety of ways that t1 could get the reference to t2.
It could be passed as a constructor parameter. (You would need to instantiate Thread2 before Thread1 ...)
It could be set by calling a setter on Thread1.
It could be retrieved from a static variable or array, or a singleton "registry" object of some kind.
It could be found by enumerating all of the threads in the ThreadGroup looking for one that matches t2's name.
public class test {
private static boolean someCondition = true;
public static void main(String[]args){
Thread t2 = new Thread(new someOtherClass("Hello World"));
Thread t1 = new Thread(new someClass(t2));
t2.start();
t1.start();
try {
t1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
static class someClass implements Runnable{
Thread stop;
public someClass(Thread toStop){
stop = toStop;
}
public void run(){
while(true){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(someCondition && !stop.isInterrupted()){
stop.interrupt();
}
}
}
}
static class someOtherClass implements Runnable{
String messageToPrint;
public someOtherClass(String s){
messageToPrint = s;
}
public void run(){
while(true){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(messageToPrint);
}
}
}
}
You could consider the use of Future interface. It provides a cancel() method.
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html
Playing with interruption makes your life unnecessarily hard. Besides the fact that your code must know the threads, interruption does not provide any context information about the reason of the interruption.
If you have a condition that is shared by your code possibly executed by different threads, just encapsulate that condition into an object and share that object:
public class Test {
public static void main(String[] args) {
Condition c=new Condition();
new Thread(new Setter(c)).start();
new Thread(new Getter(c, "getter 1")).start();
// you can simply extend it to more than one getter:
new Thread(new Getter(c, "getter 2")).start();
}
}
class Getter implements Runnable {
final Condition condition;
final String name;
Getter(Condition c, String n) { condition=c; name=n; }
public void run() {
while(!condition.isSatisfied()) {
System.out.println(name+" doing something else");
try { Thread.sleep(300); } catch(InterruptedException ex){}
}
System.out.println(name+" exiting");
}
}
class Setter implements Runnable {
final Condition condition;
Setter(Condition c) { condition=c; }
public void run() {
System.out.println("setter: doing my work");
try { Thread.sleep(3000); }
catch(InterruptedException ex){}
System.out.println("setting condition to satisfied");
condition.setSatisfied();
}
}
class Condition {
private volatile boolean satisfied;
public void setSatisfied() {
satisfied=true;
}
public boolean isSatisfied() {
return satisfied;
}
}
The big advantage of this encapsulation is that it is easy to extend. Suppose you want to allow a thread to wait for the condition instead of polling it. Taking the code above it’s easy:
class WaitableCondition extends Condition {
public synchronized boolean await() {
try {
while(!super.isSatisfied()) wait();
return true;
} catch(InterruptedException ex){ return false; }
}
public synchronized void setSatisfied() {
if(!isSatisfied()) {
super.setSatisfied();
notifyAll();
}
}
}
class Waiter implements Runnable {
final WaitableCondition condition;
final String name;
Waiter(WaitableCondition c, String n) { condition=c; name=n; }
public void run() {
System.out.println(name+": waiting for condition");
boolean b=condition.await();
System.out.println(name+": "+(b? "condition satisfied": "interrupted"));
}
}
Without changing the other classes you can now extend your test case:
public class Test {
public static void main(String[] args) {
WaitableCondition c=new WaitableCondition();
new Thread(new Setter(c)).start();
new Thread(new Getter(c, "getter 1")).start();
// you can simply extend it to more than one getter:
new Thread(new Getter(c, "getter 2")).start();
// and you can have waiters
new Thread(new Waiter(c, "waiter 1")).start();
new Thread(new Waiter(c, "waiter 2")).start();
}
}

Trying to loop 3 threads in a specific order everytime

My question is how do I make a thread run, then after that another run, then after that another run again, then it repeats itself.
I have a main file
private static ThreadManager threadManager;
public static void main(String[] args)
{
threadManager = new ThreadManager();
}
Then I have a ThreadManager class
public class ThreadManager {
public static final Object lock1 = new Object();
public static ConcThread CT = new ConcThread();
public static SocketThread sThread = new SocketThread();
public static PacketThread packetThread = new PacketThread();
public ThreadManager() {
try {
synchronized (lock1) {
packetThread.packetThread.start();
lock1.wait();
CT.concThread.start();
lock1.wait();
sThread.socketThread.start();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Then I have 3 threads
public class PacketThread implements Runnable {
public Thread packetThread = new Thread(this);
public void run() {
while (true) {
try {
synchronized (ThreadManager.lock1) {
//DoThing1
synchronized (this) {
ThreadManager.lock1.notifyAll();
}
ThreadManager.lock1.wait();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public class ConcThread implements Runnable {
public Thread concThread = new Thread(this);
public void run() {
while (true) {
synchronized (ThreadManager.lock1) {
try {
//dothing2
synchronized (this) {
ThreadManager.lock1.notifyAll();
}
ThreadManager.lock1.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
public class SocketThread implements Runnable {
public Thread socketThread = new Thread(this);
public void run() {
while (true) {
synchronized (ThreadManager.lock1) {
try {
//dothing3
synchronized (this) {
ThreadManager.lock1.notifyAll();
}
ThreadManager.lock1.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
Rather than having a single lock shared between the three threads (which is in-determinant on which thread will pick up after a thread releases the lock), have three separate semaphore/locks, where thread #1 unlocks a semaphore for thread #2 after its task is complete, thread #2 unlocks the semaphore for thread #3, and thread #3 unlocks the semaphore for thread #1.
So it would look something like:
Thread #1 runs (thread #2 and thread #3 are currently blocked)
Thread #1 completes
Thread #1 unlocks semaphore for thread #2
Thread #1 blocks
Thread #2 runs
Thread #2 completes
Thread #2 unlocks semaphore for thread #3
Thread #2 blocks
Thread #3 runs
Thread #3 completes
Thread #3 unlocks semaphore for thread #1
Thread #3 blocks
Hope this helps,
Jason
Have you considered looking at Runnable to identify the chunks of work you have, and an appropriate Executor to control what runs when?

Categories

Resources