Reputation: 35
I am trying to make my threads follow each other like its a race and a want the threads to wait for each other. Like:
DUCK is on his 1 lap
PIGGY is on his 1 lap
ELEFANT is on his 1 lap
STAR is on his 1 lap
DUCK is on his 2 lap
PIGGY is on his 2 lap
ELEFANT is on his 2 lap
STAR is on his 2 lap
and so on..
public class ExThread implements Runnable {
String name;
Random r = new Random();
int count;
int sleepTimer;
public ExThread(String name) {
this.name = name;
}
@Override
public void run() {
try {
for(int i = 0; i < 10; i++) {
count++;
sleepTimer = r.nextInt(1000)+1;
Thread.sleep(sleepTimer);
System.out.println(
name + " Starts after "+sleepTimer+" milliseconds break");
System.out.println(
name+" is on his "+count+" lap");
}
System.out.println(name+" completes the race!!!");
}
catch (Exception e){}
}
public class ThreadsEx {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new ExThread("STAR"));
Thread t2 = new Thread(new ExThread("ELEFANT"));
Thread t3 = new Thread(new ExThread("PIGGY"));
Thread t4 = new Thread(new ExThread("DUCK"));
t1.start();
t2.start();
t3.start();
t4.start();
}
}
Upvotes: 1
Views: 1242
Reputation: 2701
You could use join.
for(i = 0; i < threads.length; i++){
threads[i].join();
}
Join will block current thread (Main thread in your case I presume). When the for loop finishes all threads will be done with their work.
In your case, you could make each thread do a single lap instead of 10.
for(j = 0; j < numberOfLaps; j++){
for(i = 0; i < threads.length; i++){
threads[i].join();
}
}
Upvotes: 0
Reputation: 14853
You have to use java.util.concurrent, like this :
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
public class RendezVous extends Thread {
private final CountDownLatch _start;
private final CyclicBarrier _rdv;
private final CountDownLatch _stop;
public RendezVous(
String name,
CountDownLatch start,
CyclicBarrier rdv,
CountDownLatch stop )
{
super( name );
_start = start;
_rdv = rdv;
_stop = stop;
start();
}
@Override
public void run() {
final Random rnd = new Random( System.currentTimeMillis());
try {
System.out.println( getName() + " is started" );
_start.countDown();
System.out.println( getName() + " waits for others" );
_start.await();
System.out.println( getName() + " is running" );
for(int count = 0, i = 0; i < 10; ++i, ++count ) {
final long sleepTimer = rnd.nextInt( 1000 ) + 1;
sleep( sleepTimer );
System.out.println( getName() +" is on his " + count + " lap" );
_rdv.await();
}
_stop.countDown();
_stop.await();
System.out.println( getName() + " completes the race" );
}
catch( final Exception e ) {
e.printStackTrace();
}
}
public static void main(String[] args) {
final CountDownLatch start = new CountDownLatch( 4 );
final CyclicBarrier rdv = new CyclicBarrier( 4 );
final CountDownLatch stop = new CountDownLatch( 4 );
new RendezVous( "STAR" , start, rdv, stop );
new RendezVous( "ELEFANT", start, rdv, stop );
new RendezVous( "PIGGY" , start, rdv, stop );
new RendezVous( "DUCK" , start, rdv, stop );
}
}
Execution log:
DUCK is started
STAR is started
DUCK waits for others
PIGGY is started
ELEFANT is started
PIGGY waits for others
STAR waits for others
PIGGY is running
STAR is running
ELEFANT waits for others
DUCK is running
ELEFANT is running
STAR is on his 0 lap
PIGGY is on his 0 lap
DUCK is on his 0 lap
ELEFANT is on his 0 lap
DUCK is on his 1 lap
STAR is on his 1 lap
ELEFANT is on his 1 lap
PIGGY is on his 1 lap
STAR is on his 2 lap
ELEFANT is on his 2 lap
PIGGY is on his 2 lap
DUCK is on his 2 lap
STAR is on his 3 lap
PIGGY is on his 3 lap
ELEFANT is on his 3 lap
DUCK is on his 3 lap
DUCK is on his 4 lap
PIGGY is on his 4 lap
ELEFANT is on his 4 lap
STAR is on his 4 lap
STAR is on his 5 lap
PIGGY is on his 5 lap
ELEFANT is on his 5 lap
DUCK is on his 5 lap
STAR is on his 6 lap
DUCK is on his 6 lap
PIGGY is on his 6 lap
ELEFANT is on his 6 lap
PIGGY is on his 7 lap
ELEFANT is on his 7 lap
STAR is on his 7 lap
DUCK is on his 7 lap
ELEFANT is on his 8 lap
DUCK is on his 8 lap
PIGGY is on his 8 lap
STAR is on his 8 lap
STAR is on his 9 lap
ELEFANT is on his 9 lap
DUCK is on his 9 lap
PIGGY is on his 9 lap
DUCK completes the race
PIGGY completes the race
ELEFANT completes the race
STAR completes the race
Upvotes: 0
Reputation: 1210
I assume the rules are:
These rules above require some form of synchronization between the threads and there are a few synchronization options available in Java
An initial proposal would be to use a value that all threads have access to so that they can communicate their progress and know if they can progress to the next lap or not and keep track of each others progress.
Some general notes to your implementation
Upvotes: 1
Reputation: 9543
Firstly, it's very bad to have multiple instances of Random
especially if they are created within milliseconds of each other (because they are seeded with random state of your computer, which doesn't change much over those time scales)
To make threads wait for each other, use a CyclicBarrier
. The javadoc as an excellent example. However, I don't think that's what you're after as this will interfere with the race itself.
What you may want is a referee thread of some sorts that periodically prints the laps that the other threads have ran so far.
Upvotes: 2
Reputation: 2622
You can use https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CyclicBarrier.html for this.
Code goes like this
import java.util.Random;
import java.util.concurrent.CyclicBarrier;
public class ExThread implements Runnable {
String name;
Random r = new Random();
int count;
int sleepTimer;
CyclicBarrier barrier;
public ExThread(String name, CyclicBarrier barrier) {
this.name = name;
this.barrier = barrier;
}
public static void main(String[] args) throws InterruptedException {
CyclicBarrier barrier = new CyclicBarrier(4);
Thread t1 = new Thread(new ExThread("STAR", barrier));
Thread t2 = new Thread(new ExThread("ELEFANT", barrier));
Thread t3 = new Thread(new ExThread("PIGGY", barrier));
Thread t4 = new Thread(new ExThread("DUCK", barrier));
t1.start();
t2.start();
t3.start();
t4.start();
}
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
count++;
sleepTimer = r.nextInt(1000) + 1;
Thread.sleep(sleepTimer);
System.out.println(
name + " Starts after " + sleepTimer + " milliseconds break");
System.out.println(
name + " is on his " + count + " lap");
barrier.await();
}
System.out.println(name + " completes the race!!!");
} catch (Exception e) {
}
}
}
Upvotes: 0