[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 434
  • Last Modified:

using semaphores to synchronize threads in java

Hi,
      I have a very simple application (see attached file) which is supposed to alternatively print  to screen;
TA going first!
TB going second!
TA going first!
TB going second!

until the process is interrupted....
i'm using 2 threads and a semaphore to synchronize thread execution, however when i put a for loop in main to show  the output as above, the output is not consistently alternating between statements as i expected.
When i comment out  the loop (currently commented out) the statements alternate as expected.
can someone have a look at  my code and see if they can highlight   the problem? Or have i misunderstood semaphores entirely?
thanks


semaphoreEx1.java
0
blossompark
Asked:
blossompark
  • 6
  • 5
1 Solution
 
mnrzCommented:
The code works fine for me! However I think you should remove the for-loop and put a while() in each thread
0
 
mnrzCommented:
This is the result. Id this what you expect?

TA going first!
TB going second!
TA going first!
TB going second!
TA going first!
TB going second!
TA going first!
TB going second!
TA going first!
TB going second!
TA going first!
TB going second!
TA going first!
TB going second!
TA going first!
TB going second!
TA going first!
TB going second!
TA going first!
TB going second!


0
 
blossomparkAuthor Commented:
hi mnrz,
no..i'm getting random results like;
TA going first!
TA going first!
TA going first!
TB going second!
TB going second!
TA going first!
TA going first!
TB going second!
TA going first!
TB going second!
TA going first!
TB going second!
TA going first!
TB going second!
TA going first!
TA going first!
TB going second!
TB going second!
TB going second!
TB going second!

Process completed.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
blossomparkAuthor Commented:
ps ...why get rid of  the for loop?
0
 
mnrzCommented:
Yes you get that result because each time you call start() method the order you run is not guaranteed to be executed as expected that is why I told you put a while in each thread and remove the for-loop from that main method
0
 
blossomparkAuthor Commented:
is that how you got  the correct output..using while loops in  the threads?
0
 
blossomparkAuthor Commented:
do you mean put a while loop in the run method of each thread?
0
 
mnrzCommented:
the result I got was actually by chance

check this code:


import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class SemaphoreEx2{
	public static void main(String args[]){
		Lock lock = new ReentrantLock();
		Condition mineA = lock.newCondition();
		Condition mineB = lock.newCondition();
		
	//for (int i=0;i<10;i++){
		new TA(lock,mineA,mineB).start();
		new TB(lock,mineA,mineB).start();
	//		} 
		
	}
}
class TA extends Thread{
	Lock lock ;
	Condition mineA;
	Condition mineB;
	public TA(Lock lock, Condition mineA,Condition mineB) {
		this.lock = lock;
		this.mineA = mineA;
		this.mineB = mineB;
	}
	public void run(){
		for (int i=0;i<10;i++){
		//put code for TA here
		try{
			lock.lock();
			System.out.println("TA going first!");
			mineB.signal();
			mineA.await();
		}catch(InterruptedException e){}
		}
	}
}

class TB extends Thread{
	Lock lock ;
	Condition mineA;
	Condition mineB;
	public TB(Lock lock, Condition mineA,Condition mineB) {
		this.lock = lock;
		this.mineA = mineA;
		this.mineB = mineB;
	}
	public void run(){
		for (int i=0;i<10;i++){
		try{
			lock.lock();
			System.out.println("TB going second!");
			mineA.signal();
			mineB.await();
		}catch(InterruptedException e){}
		//put code for TB here
		}	

	}
}

Open in new window

0
 
mnrzCommented:
sorry I forgot to put finally block

and please note that this is not guaranteed that the TA is executing first but the order will be guaranteed. if you want the TA always runs first you need to put a delay between TA start() method and TB start() method

import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class SemaphoreEx2{
	public static void main(String args[]){
		Lock lock = new ReentrantLock();
		Condition mineA = lock.newCondition();
		Condition mineB = lock.newCondition();
		
		new TA(lock,mineA,mineB).start();
		new TB(lock,mineA,mineB).start();
		
	}
}

class TA extends Thread{
	Lock lock ;
	Condition mineA;
	Condition mineB;
	public TA(Lock lock, Condition mineA,Condition mineB) {
		this.lock = lock;
		this.mineA = mineA;
		this.mineB = mineB;
	}
	public void run(){
		for (int i=0;i<10;i++){
		//put code for TA here
		try{
			lock.lock();
			System.out.println("TA going first!");
			mineB.signal();
			mineA.await();
		}catch(InterruptedException e){}
		finally{
			lock.unlock();
		}
		}
	}
}
class TB extends Thread {
	Lock lock ;
	Condition mineA;
	Condition mineB;
	public TB(Lock lock, Condition mineA,Condition mineB) {
		this.lock = lock;
		this.mineA = mineA;
		this.mineB = mineB;
	}
	public void run(){
		for (int i=0;i<10;i++){
			try{
				lock.lock();
				System.out.println("TB going second!");
				mineA.signal();
				mineB.await();
			}catch(InterruptedException e){}
			finally{
				lock.unlock();
			}
			
		}
	}
} 
	

Open in new window

0
 
blossomparkAuthor Commented:
thanks mnrz...will put in delay as suggested also
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

  • 6
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now