In multithreading: How to determine which thread stops first - java

Write a class named RaceHorse that extends Thread. Each RaceHorse has a name and run() method that displays the name 5000 times. Write a Java application that instantiates 2 RaceHorse objects. The last RaceHorse to finish is the loser.
This is the question.
I have written the code for the two classes two run the thread
Here are the codes:
RaceHorse
class RaceHorse extends Thread
{
public String name;
public RaceHorse(String name)
{
this.name = name;
}
public void run()
{
for(int i = 1 ; i <= 5000; i++)
{
System.out.println(i+" "+name);
}
System.out.println(name+" finished.");
}
}
Runner
class Runner{
public static void main(String args[])
{
RaceHorse obj = new RaceHorse("Lol");
RaceHorse obj2 = new RaceHorse("BOL");
Thread t = new Thread(obj);
Thread t2 = new Thread(obj2);
t.start();
t2.start();
}
}
Now my problem is I am unable to find which of the thread finishes first and which seconds, i.e. which of the horse wins and which loses.!

First off: your RaceHorse objects are themselves threads. You should be able to say obj.start(); and it'd work just as well. So remove t and t2 entirely.
Next, you'll need some way to notify the main thread about the winner.
public void run()
{
... your loop stuff ...
// this is how we're going to do the notification.
Runner.done();
}
public class Runner
{
private static RaceHorse winner = null;
synchronized static void done()
{
// Threads calling this are going to be RaceHorse objects.
// Now, if there isn't already a winner, this RaceHorse is the winner.
if (winner == null) winner = (RaceHorse) Thread.currentThread();
}
public static void main(String[] args)
{
... create the horses ...
// start the horses running
obj.start();
obj2.start();
// wait for them to finish
obj.join();
obj2.join();
System.out.println(winner.name + " wins!");
}
}

There's no doubt a better way, but one method might be to create a class (e.g. 'Trophy') that is thread safe, has a method 'getTrohpy' that only returns true on the first call, and pass a reference to an instance of Trophy to both threads.

public class StackOverflow {
public static void main(String[] args) {
RaceHorse obj = new RaceHorse("Lol");
RaceHorse obj2 = new RaceHorse("BOL");
Thread t = new Thread(obj);
Thread t2 = new Thread(obj2);
t.start();
t2.start();
}
}
class RaceHorse extends Thread
{
//public String name;
public RaceHorse(String name)
{
this.setName(name);
}
public void run()
{
for(int i = 1 ; i <= 5000; i++)
{
System.out.println(i+" "+this.getName());
try {
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(this.getName()+" finished.");
}
}

As cHao pointed out, RaceHorse extends Thread but you are creating a new Thread per horse. I would solve it the opposite way, by having RaceHorse implement Runnable instead.
Secondly, the solution using a synchronized method will work, but a general rule is always look for a class in java.util.concurrent that will solve the problem first. This one can be solved using an AtomicReference to ensure that only one horse takes the trophy.
Lastly, there could be a bias in favour of horse #1, if the main thread starts the horses' threads in a fixed order (this depends on the VM and on the overhead of starting a new thread on your OS.) Consider using a signal (for example a CountDownLatch) that all horses wait for before starting.
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
public class Runner {
public static void main(String args[]) {
AtomicReference<RaceHorse> winner =
new AtomicReference<RaceHorse>();
CountDownLatch startingPistol = new CountDownLatch(1);
RaceHorse horse1 = new RaceHorse("Lol", startingPistol, winner);
RaceHorse horse2 = new RaceHorse("BOL", startingPistol, winner);
Thread thread1 = new Thread(horse1);
Thread thread2 = new Thread(horse2);
thread1.start();
thread2.start();
startingPistol.countDown();
}
}
class RaceHorse implements Runnable {
private final String name;
private final CountDownLatch startingPistol;
private final AtomicReference<RaceHorse> winner;
public RaceHorse(String name,
CountDownLatch startingPistol,
AtomicReference<RaceHorse> winner)
{
this.name = name;
this.startingPistol = startingPistol;
this.winner = winner;
}
public void run()
{
try {
startingPistol.await();
for(int i = 1 ; i <= 5000; i++)
{
System.out.println(i+" "+name);
}
boolean iWon = winner.compareAndSet(null, this);
System.out.printf("%s %s.%n", name, iWon? "won": "lost");
} catch (InterruptedException ex) {
System.out.printf("%s was assasinated before the race started.%n", name);
Thread.currentThread().interrupt();
}
}
}

I am not going to write the code for you; but you should take a look at the notify method (see here) to be used.
One approach could be: once a thread has finished it will wait() for the other thread(s) to notify (or notifyAll()).
Another, more elegant solution, would consist of using a synchronized block on a shared object; the syncrhonized(obj) statement would be at the end of the run() method. Into that statement you could put a printline or any other code you would deem useful to determine who won the race.

This will work at the end of the main :
boolean alive1 = true;
boolean alive2 = true;
while (alive1 && alive2) {
alive1 = obj.isAlive();
alive2 = obj2.isAlive();
if (!alive1 && !alive2) {
// Too close to call
}
if (!alive1) {
// obj wins,
}
if (!alive2) {
// obj2 wins,
}
}

I'm late to the party, but I found this while looking for how to process the first result from a number of running threads. I think the easiest way is to use an ArrayBlockingQueue which gives you something like this.
public class RaceHorse extends Thread {
private ArrayBlockingQueue<RaceHorse> finishedRaceHorses;
public RaceHorse(String name) {
super(name);
}
public void run() {
for (int i = 1; i <= 50; i++) {
System.out.println(i + " " + getName());
}
System.out.println(getName() + " finished.");
finishedRaceHorses.offer(this);
}
public void setFinishedRaceHorses(ArrayBlockingQueue<RaceHorse> finishedRaceHorses) {
this.finishedRaceHorses = finishedRaceHorses;
}
}
public class Race {
private final List<RaceHorse> raceHorses;
public Race(List<RaceHorse> raceHorses) {
this.raceHorses = raceHorses;
}
public RaceHorse go() throws InterruptedException {
ArrayBlockingQueue<RaceHorse> finishedRaceHorses = new ArrayBlockingQueue<RaceHorse>(raceHorses.size());
for (RaceHorse raceHorse : raceHorses) {
raceHorse.setFinishedRaceHorses(finishedRaceHorses);
raceHorse.start();
}
return finishedRaceHorses.take();
}
}
public class Runner {
public static void main(String args[])
{
RaceHorse horseOne = new RaceHorse("Lol");
RaceHorse horseTwo = new RaceHorse("BOL");
Race race = new Race(Arrays.asList(horseOne, horseTwo));
try {
RaceHorse winner = race.go();
System.out.println("The winner is " + winner.getName());
} catch (InterruptedException e) {
System.out.println("The race was interrupted, maybe by a streaker?");
}
}
}

I have tried this problem and solved it using following code. There is room for improvement but for me this code worked perfectly :
1.RacingGame.java
/
package game;
import gamingObject.Horse;
import gamingObject.Race;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class RacingGame {
/**
* #param args
*/
public static Map<Integer, List<String>> raceToWinners = new HashMap<Integer, List<String>>();
public static int currentRace = 1;
public static boolean trackComplete = false;
private static boolean newTrackBegin;
private static boolean flag = true;
private static boolean race6Begin = false;
private static boolean race7Begin = false;
private static Object mutex = new Object();
private int frstHorseInNextRace = 0;
public static void main(String[] args) throws InterruptedException {
ExecutorService exeService = Executors.newFixedThreadPool(5);
/*
* Logic to conduct first 5 races (total horses/total track) so here
* total horses = 25 and tracks = 5 hence initial and compolsuary races
*/
RacingGame rg = new RacingGame();
for (int race = 1; race <= 5; race++) {
trackComplete = false;
currentRace = race;
while (!trackComplete) {
rg.startTrack();
}
}
/*
* Before 6th Race lets have right candidate for 6th race
*/
List<String> horseNames = chooseHorsesForRace6();
/*
* Race among 5 tops horses from 5 races
*/
currentRace++;
synchronized (mutex) {
while (!race6Begin) {
race(horseNames);
}
}
/*
* Choose candidates for last race 7
*/
horseNames = chooseHorsesForRace7();
currentRace++;
synchronized (mutex) {
while (!race7Begin) {
race(horseNames);
}
}
printResults();
System.exit(0);
}
private static void printResults() {
// TODO Auto-generated method stub
Iterator<Integer> iter = raceToWinners.keySet().iterator();
while (iter.hasNext()) {
int raceNum = iter.next();
StringBuffer sb = new StringBuffer();
System.out.println("Race" + raceNum + " : ");
List<String> horses = raceToWinners.get(raceNum);
for (int i = 0; i < 3; i++) {
sb.append(horses.get(i));
if (i < 2)
sb.append(",");
}
System.out.print(sb.toString());
System.out.println();
}
}
private static List<String> chooseHorsesForRace7() {
/*
* Adding First horse at first rank among 25 horses
*/
List<String> winners = new ArrayList<String>();
winners.add(raceToWinners.get(6).get(0));
raceToWinners.put(7, winners);
/*
* Taking first horses from races 2 and 3
*/
List<String> finalTrackHorses = new ArrayList<String>();
finalTrackHorses.add(raceToWinners.get(6).get(1));// firstHorse
finalTrackHorses.add(raceToWinners.get(6).get(2));// secondHorse
/*
* Rejecting all horses from race track whose first horses are at 4th
* and 5th rank of race 6
*/
for (int i = 1; i <= 5; i++) {
if (raceToWinners.get(i).contains(winners.get(0))) {
finalTrackHorses.add(raceToWinners.get(i).get(1));// thirdHorse
finalTrackHorses.add(raceToWinners.get(i).get(2));// forth horse
} else if (raceToWinners.get(i).contains(finalTrackHorses.get(1))) {
finalTrackHorses.add(raceToWinners.get(i).get(1));// fifth horse
}
}
return finalTrackHorses;
}
private static void race(List<String> horseNames) throws InterruptedException {
if (currentRace == 6)
race6Begin = true;
else
race7Begin = true;
newTrackBegin = true;
flag = true;
trackComplete = false;
while (flag) {
if (!trackComplete) {
/*
* Create thread for each horse
*
* Here taking slot of 5 horses and keep them running in a
* single loop.
*/
if (newTrackBegin) {
List<String> horses = Arrays.asList(horseNames.get(0),
horseNames.get(1), horseNames.get(2),
horseNames.get(3), horseNames.get(4));
Race r = new Race(horses);
r.start();
}
newTrackBegin = false;
mutex.wait(1);
} else if (trackComplete) {
mutex.notify();
flag = false;
}
}
}
private static List<String> chooseHorsesForRace6() {
List<String> lstHorses = new ArrayList<String>();
for (int i = 1; i <= 5; i++) {
/*
* Take only 1st Position Holders of first 5 races
*/
lstHorses.add(raceToWinners.get(i).get(0));
}
return lstHorses;
}
public Map<Integer, List<String>> getRaceToWinners() {
return raceToWinners;
}
public static synchronized void addTrackWinnerInList(String horseName) {
List<String> horses = raceToWinners.get(currentRace);
if (horses == null) {
List<String> raceHorses = new ArrayList<String>();
raceHorses.add(horseName);
raceToWinners.put(currentRace, raceHorses);
} else {
horses.add(horseName);
raceToWinners.put(currentRace, horses);
}
if (raceToWinners.get(currentRace) != null
&& raceToWinners.get(currentRace).size() == 5) {
trackComplete = true;
}
}
public static boolean isTrackComplete(){
return trackComplete;
}
public void startTrack() throws InterruptedException {
// TODO Auto-generated method stub
synchronized (mutex) {
flag = true;
newTrackBegin = true;
trackComplete = false;
while (!trackComplete) {
/*
* Create thread for each horse
*
* Here taking slot of 5 horses and keep them running in a
* single loop.
*/
if (newTrackBegin) {
List<String> horses = Arrays.asList("Horse"
+ (++frstHorseInNextRace), "Horse"
+ (++frstHorseInNextRace), "Horse"
+ (++frstHorseInNextRace), "Horse"
+ (++frstHorseInNextRace), "Horse"
+ (++frstHorseInNextRace));
Race r = new Race(horses);
r.start();
}
newTrackBegin = false;
}
}
}
}
2.Horse.java
package gamingObject;
import game.RacingGame;
public class Horse extends Thread{
String horseName;
public Horse(String horseName){
this.horseName = horseName;
}
#Override
public void run() {
for (int i = 0; i < 5; i++) {
try {
sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
RacingGame.addTrackWinnerInList(this.horseName);
}
}
3.Race.java
package gamingObject;
import game.RacingGame;
import java.util.List;
public class Race extends Thread {
List<String> horses;
private boolean flag = true;
private Object obj = new Object();
public Race(List<String> horses) {
this.horses = horses;
}
public void startRace() {
synchronized (obj) {
run();
}
}
#Override
public void run() {
synchronized (obj) {
boolean newTrackBegin = true;
while (!RacingGame.isTrackComplete()) {
/*
* Create thread for each horse
*
* Here taking slot of 5 horses and keep them running in a
* single loop.
*/
if (newTrackBegin) {
Horse h1 = new Horse(horses.get(0));
Horse h2 = new Horse(horses.get(1));
Horse h3 = new Horse(horses.get(2));
Horse h4 = new Horse(horses.get(3));
Horse h5 = new Horse(horses.get(4));
Thread t1 = new Thread(h1);
Thread t2 = new Thread(h2);
Thread t3 = new Thread(h3);
Thread t4 = new Thread(h4);
Thread t5 = new Thread(h5);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
newTrackBegin = false;
}else{
if(!RacingGame.isTrackComplete()){
try {
obj.wait(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
obj.notify();
}
}
}
}
}
}

Related

Programme not Terminating in Multi-threaded environment -Java

Trying to make a simple multi-threaded programme where it prints Factorial series where each number is printed by different Thread and at the end I am giving a report of which number printed by which thread.I have got the desired output but somehow my program is not terminating.
Constraint: I am not allowed to use Concurrent Package
import java.util.ArrayList;
import java.util.Scanner;
class Report {
private long factorial;
private String threadName;
private int activeThreads;
public Report(long factorial, String threadName, int activeThreads) {
this.factorial = factorial;
this.threadName = threadName;
this.activeThreads = activeThreads;
}
public long getFactorial() {
return factorial;
}
public String getThreadName() {
return threadName;
}
public int getActiveThreads() {
return activeThreads;
}
public void setActiveThreads(int activeThreads) {
this.activeThreads = activeThreads;
}
}
public class Factorial implements Runnable {
public static ArrayList<Report> report = new ArrayList<Report>();
private static int count;
public static void main(String[] args) throws InterruptedException {
Scanner in = new Scanner(System.in);
System.out.print("N: ");
int n = in.nextInt();
count = n;
Factorial f = new Factorial();
f.series(n);
Thread.sleep(1000);
// Series
for(Report r : report) {
if(r.getFactorial() == 1) {
System.out.print(r.getFactorial());
}
else {
System.out.print(r.getFactorial() + "*");
}
}
System.out.println();
// Report
for(Report r : report) {
System.out.println(r.getFactorial() + " printed by " + r.getThreadName() + " " + r.getActiveThreads());
}
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
System.out.println("In Main");
in.close();
}
public void series(int n) throws InterruptedException {
for(int i=0;i<n;i++) {
Thread t = new Thread(new Factorial());
t.start();
}
}
public synchronized void generate() {
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
report.add(new Report(count--, Thread.currentThread().getName(), threadGroup.activeCount()));
notifyAll();
System.out.println("In generate" + threadGroup.activeCount());
}
#Override
public void run() {
generate();
synchronized (this) {
try {
wait();
}
catch(Exception e) {
e.printStackTrace();
}
}
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
System.out.println("In Run" + threadGroup.activeCount());
}
public static int getCount() {
return count;
}
public static void setCount(int count) {
Factorial.count = count;
}
}
Although I know that we can kill the threads using .stop() but I think it's not recommended.
To make synchronization effective (synchronized, wait, notify), you have to use the same instance.
In series, you create a new Factorial instance on each loop, making every thread to wait indefinitely.
public void series(int n) throws InterruptedException {
for(int i=0;i<n;i++) {
// Thread t = new Thread(new Factorial()); // creates an new instance
Thread t = new Thread(this);
t.start();
}
}
In the run method, you first call notifyAll() (through generate), and then wait.
The last created thread will wait after all the others are done.
One way or another, this last thread has to be notified.
It could be right after the sleep call, with:
synchronized(f) {
f.notify();
}
or maybe with a dedicated synchronized method.

print even and odd using 2 threads

Hi I am trying to print even and odd using two threads namedly EvenThread and OddThread, some times I am getting correct result and some times not, could any one please help me.
package com.java8;
public class EvenOddExample {
public static synchronized void print(int i,String name){
System.out.println(i+"--->"+name);
}
public static void main(String[] args) throws InterruptedException {
EvenThread e= new EvenThread();
e.start();
OddThread o=new OddThread();
o.start();
}
public static class EvenThread extends Thread{
public void run() {
for(int i=0;i<10;i++){
if(i%2==0){
print(i,"Even");
}else{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public static class OddThread extends Thread{
#Override
public void run() {
for(int i=1;i<10;i++){
if(i%2!=0){
print(i,"Odd");
}else{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
You need some signaling between the two threads. Putting synchronized on the print method simply guarantees, that only one thread can enter the method at a time. To put your threads into order Object.wait() and Object.notify{All}() methods can be used.
Actually this is some kind of the Sender-Receiver Synchronization Problem. Based on the example of the problem described here (Please read this page in order to understand how this synchronization works) I adapted your code. Additionally I used ExecutorService and Callable instead of extending Thread, which is bad-practice:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class EvenOddExample {
private static boolean evensTurn = true;
private static Object monitor = new Object();
public static void print(int i, String name) {
System.out.println(i + "--->" + name);
}
public static void main(String[] args) throws InterruptedException {
final ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(new EvenCallable());
executorService.submit(new OddCallable());
executorService.shutdown();
}
public static class EvenCallable implements Callable<Void> {
#Override
public Void call() throws InterruptedException {
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
synchronized (monitor) {
while (!evensTurn) { // not your turn?
monitor.wait(); // wait for monitor in a loop to handle spurious wakeups
}
print(i, "Even");
evensTurn = false; // next odd needs to run
monitor.notifyAll(); // wakeup the odd thread
}
} else {
Thread.sleep(1000);
}
}
return null;
}
}
public static class OddCallable implements Callable<Void> {
#Override
public Void call() throws InterruptedException {
for (int i = 1; i < 10; i++) {
if (i % 2 != 0) {
synchronized (monitor) {
while (evensTurn) {
monitor.wait();
}
print(i, "Odd");
evensTurn = true;
monitor.notifyAll();
}
} else {
Thread.sleep(1000);
}
}
return null;
}
}
}
synchronized is used to lock the access of another thread, when the locked object is free, it does not guarantee which is next called thread. You can use semaphore to make inter-thread communication:
private static Semaphore[] semaphores = {new Semaphore(0), new Semaphore(1)};
static void print(int i, String name) {
try {
semaphores[(i + 1) % 2].acquire();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println(i + "--->" + name);
semaphores[i % 2].release();
}
public class EvenOddPrinter {
static boolean flag = true;
public static void main(String[] args) {
class Odd implements Runnable {
#Override
public void run() {
for (int i = 1; i <= 10;) {
if (EvenOddPrinter.flag) {
System.out.println(i + "--->odd");
i += 2;
EvenOddPrinter.flag = !EvenOddPrinter.flag;
}
}
}
}
class Even implements Runnable {
#Override
public void run() {
for (int i = 2; i <= 10;) {
if (!EvenOddPrinter.flag) {
System.out.println(i + "---->even");
i += 2;
EvenOddPrinter.flag = !EvenOddPrinter.flag;
}
}
}
}
Runnable odd = new Even();
Runnable even = new Odd();
Thread t1 = new Thread(odd, "Odd");
Thread t2 = new Thread(even, "Even");
t1.start();
t2.start();
}
}

How can i get class variable in run method thread (Java)

My problem concern thread. i want to get var(class variable) from method run but can't get and
i don't know what happed.
import java.util.ArrayList;
public class Interpreter_controller extends Thread{
ArrayList<String> var;
public Interpreter_controller(ArrayList<String> var) {
this.var = var;
System.out.println(this.var.isEmpty());
}
public void run() {
System.out.println(this.var.isEmpty());
}
}
when i start thread from
Interpreter_controller control = new Interpreter_controller(array_list_variable);
control.start();
Output is
false
true
What should I do to get var from run method?
New Edit
I delete extends Thread then result is correct but i want to use thread in this class
My goal is pass arraylist from another class to use in thread class(run method)
Hi Following will give you head start. Make sure list is synchronized.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class Main {
public static void main(String[] args) throws InterruptedException {
Main m = new Main();
m.execute();
}
public void execute() throws InterruptedException {
List<String> list = new ArrayList<String>();
list = Collections.synchronizedList(list);
List<Thread> tlist = new ArrayList<Thread>();
for (int i = 0; i < 5; i++) {
Thread t = new SomeThread(list, i);
t.start();
tlist.add(t);
}
while (true) {
int j = 0;
for (int i = 0; i < tlist.size(); i++) {
Thread.sleep(100);
if (!tlist.get(i).isAlive()) {
j++;
for (String s : list) {
System.out.println(s);
}
}
}
if (j == tlist.size()) {
break;
}
}
}
public class SomeThread extends Thread {
private List<String> list;
private int number;
private long sleepTime;
public SomeThread(List list, int number) {
this.list = list;
this.number = number;
sleepTime = new Random(number).nextInt(500);
}
#Override
public void run() {
try {
Thread.sleep(sleepTime);
list.add(number + " wake up from sleep");
} catch (InterruptedException e) {
System.out.println(e);
}
}
}
}
My goal is pass arraylist from another class to use in thread
class(run method)
Take a look at this:
class Tmp implements Runnable {
public Object runArg;
public Tmp(Object arg) {
runArg = arg;
}
public void run() {
// thread job
}
}
Use:
new Thread(new Tmp("Hello World")).start();
So you have to create a new class rather than using anonymous class.
NOTE: Unless you are using J2ME, you should NOT use native Thread. Many problems would occur with you. You should use ExecutorService by using Executors classes:
private final ExecutorService pool = Executors.newCashedThreadPool();
...
pool.submit(new Tmp("HelloWorld"));

Generate a sequence of two numbers printing even and odd number?

There are 2 threads one printing { 1,3,5,7,9} .Another printing {2,4,6,8,10}
I want to print {1,2,3,4,5,6,7...}
package com.oddnumber.threading;
public class NumberPrint implements Runnable {
int number=1;
private Object lock = new Object();
private volatile boolean isOdd = false;
public void generateEvenNumbers(int number) throws InterruptedException {
synchronized (lock) {
while (isOdd == false) {
lock.wait();
}
System.out.println("even" + number);
isOdd = false;
lock.notifyAll();
}
}
public void generateOddNumbers(int number) throws InterruptedException {
synchronized (lock) {
while (isOdd == true) {
lock.wait();
}
System.out.println("odd" + number);
isOdd = true;
lock.notifyAll();
}
}
#Override
public void run() {
while(true) {
if(number%2 == 0) {
try {
generateEvenNumbers(number);
number++;
Thread.sleep(1112);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
try {
generateOddNumbers(number);
number++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
I have executed it using:
package com.oddnumber.threading;
public class Test
{
public static void main(String[] args) {
NumberPrint n1 = new NumberPrint();
NumberPrint n2 = new NumberPrint();
new Thread(n1).start();
new Thread(n2).start();
}
}
Output:
1
1
2
2
3
3
4
4
5
5
6
6
7
8
7
8
9
9
10
Each number is printing twice, but why is the number variable is not shared between the two threads?
Each instance of the NumberPrint class has its own instance of the lock object. Using synchronized on the two different instances will have no effect. The methods must use the same object. One way would be for the main() method to create an instance of an object and pass it to the NumberPrint constructor so that there is only one instance that all the methods use to synch on.
First you need to make your variables in NumberPrint static (and probably static volatile) so that they will be shared between the two threads. This should be done for number, lock, and isOdd. If that's all you do, though, your output will be {1, 2, 1, 4, 5, 6, 7, 8, ...} because the two threads both read number as quickly as they can when they start running, without any synchronization. The best solution seems to be to make sure generateEvenNumbers and generateOddNumbers read the shared number after they synchronize--which means getting rid of the number parameter to those routines, and then when they read number it will be the shared one.
As NormR said the two threads have to share the same lock, eg:
public class Main {
public static void main(String[] args) throws InterruptedException {
Object lock = new Object();
Thread evenThread = new Thread(new GeneratorHandler(lock, new EvenGenerator()));
Thread oddThread = new Thread(new GeneratorHandler(lock, new OddGenerator()));
oddThread.start();
Thread.sleep(500);
evenThread.start();
}
}
public interface Generator {
public int generate();
}
public class EvenGenerator implements Generator {
int n = 0;
#Override
public int generate() {
return n += 2;
}
}
public class OddGenerator implements Generator {
int n = -1;
#Override
public int generate() {
return n += 2;
}
}
public class GeneratorHandler implements Runnable {
private Object lock;
private Generator generator;
public GeneratorHandler(Object lock, Generator generator) {
this.lock = lock;
this.generator = generator;
}
#Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(lock){
System.out.println(generator.generate());
}
}
}
}
public class PrintOnetoTen {
public static void main(String[] args) {
SharedPrinter sp = new SharedPrinter();
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.submit(new EvenNumberProducer(sp, 10));
executor.submit(new OddNumberProducer(sp , 10));
executor.shutdown();
}
}
class SharedPrinter {
Semaphore semEven = new Semaphore(0);
Semaphore semOdd = new Semaphore(1);
public void printEvenNumber(int num) {
try {
semEven.acquire();
}catch(InterruptedException exception) {
}
System.out.println("Thread 2 - Number : " +num);
semOdd.release();
}
public void printOddNumber(int num) {
try {
semOdd.acquire();
}catch(InterruptedException exception) {
}
System.out.println("Thread 1 - Number : " +num);
semEven.release();
}
}
class EvenNumberProducer implements Runnable {
SharedPrinter sp;
int index;
EvenNumberProducer(SharedPrinter sp , int index) {
this.sp = sp;
this.index = index;
}
#Override
public void run() {
for(int i = 2 ; i <= index ; i = i + 2 ) {
sp.printEvenNumber(i);
}
}
}
class OddNumberProducer implements Runnable{
SharedPrinter sp;
int index;
OddNumberProducer(SharedPrinter sp , int index) {
this.sp = sp;
this.index = index;
}
#Override
public void run() {
for(int i = 1 ; i <= index ; i = i + 2) {
sp.printOddNumber(i);
}
}
}
Output of the programs is :
Thread 1 - Number : 1
Thread 2 - Number : 2
Thread 1 - Number : 3
Thread 2 - Number : 4
Thread 1 - Number : 5
Thread 2 - Number : 6
Thread 1 - Number : 7
Thread 2 - Number : 8
Thread 1 - Number : 9
Thread 2 - Number : 10

Ordering threads to run in the order they were created/started

How can i order threads in the order they were instantiated.e.g. how can i make the below program print the numbers 1...10 in order.
public class ThreadOrdering {
public static void main(String[] args) {
class MyRunnable implements Runnable{
private final int threadnumber;
MyRunnable(int threadnumber){
this.threadnumber = threadnumber;
}
public void run() {
System.out.println(threadnumber);
}
}
for(int i=1; i<=10; i++){
new Thread(new MyRunnable(i)).start();
}
}
}
Sounds like you want ExecutorService.invokeAll, which will return results from worker threads in a fixed order, even though they may be scheduled in arbitrary order:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadOrdering {
static int NUM_THREADS = 10;
public static void main(String[] args) {
ExecutorService exec = Executors.newFixedThreadPool(NUM_THREADS);
class MyCallable implements Callable<Integer> {
private final int threadnumber;
MyCallable(int threadnumber){
this.threadnumber = threadnumber;
}
public Integer call() {
System.out.println("Running thread #" + threadnumber);
return threadnumber;
}
}
List<Callable<Integer>> callables =
new ArrayList<Callable<Integer>>();
for(int i=1; i<=NUM_THREADS; i++) {
callables.add(new MyCallable(i));
}
try {
List<Future<Integer>> results =
exec.invokeAll(callables);
for(Future<Integer> result: results) {
System.out.println("Got result of thread #" + result.get());
}
} catch (InterruptedException ex) {
ex.printStackTrace();
} catch (ExecutionException ex) {
ex.printStackTrace();
} finally {
exec.shutdownNow();
}
}
}
"I actually have some parts that i want to execute in parallel, and then once the results are generated, I want to merge the results in certain order." Thanks, this clarifies what you're asking.
You can run them all at once, but the important thing is to get their results in order when the threads finish their computation. Either Thread#join() them in the order in which you want to get their results, or just Thread#join() them all and then iterate through them to get their results.
// Joins the threads back to the main thread in the order we want their results.
public class ThreadOrdering {
private class MyWorker extends Thread {
final int input;
int result;
MyWorker(final int input) {
this.input = input;
}
#Override
public void run() {
this.result = input; // Or some other computation.
}
int getResult() { return result; }
}
public static void main(String[] args) throws InterruptedException {
MyWorker[] workers = new MyWorker[10];
for(int i=1; i<=10; i++) {
workers[i] = new MyWorker(i);
workers[i].start();
}
// Assume it may take a while to do the real computation in the threads.
for (MyWorker worker : workers) {
// This can throw InterruptedException, but we're just passing that.
worker.join();
System.out.println(worker.getResult());
}
}
}
Simply put, the scheduling of threads is indeterminate.
http://www.janeg.ca/scjp/threads/scheduling.html Dead domain - do not click
WaybackMachine version of the above page
The longer answer is that if you want to do this, you'll need to manually wait for each thread to complete its work before you allow another to run. Note that in this fashion, all the threads will still interleave but they won't accomplish any work until you give the go-ahead. Have a look at the synchronize reserved word.
You can chain them – that is, have the first one start the second, the second start the third, etc. They won't really be running at the same time except for a bit of overlap when each one is started.
public class ThreadOrdering
{
public static void main(String[] args)
{
MyRunnable[] threads = new MyRunnable[10];//index 0 represents thread 1;
for(int i=1; i<=10; i++)
threads[i] = new MyRunnable(i, threads);
new Thread(threads[0].start);
}
}
public class MyRunnable extends Runnable
{
int threadNumber;
MyRunnable[] threads;
public MyRunnable(int threadNumber, MyRunnable[] threads)
{
this.threadnumber = threadnumber;
this.threads = threads;
}
public void run()
{
System.out.println(threadnumber);
if(threadnumber!=10)
new Thread(threadnumber).start();
}
}
Here's a way to do it without having a master thread that waits for each result. Instead, have the worker threads share an object which orders the results.
import java.util.*;
public class OrderThreads {
public static void main(String... args) {
Results results = new Results();
new Thread(new Task(0, "red", results)).start();
new Thread(new Task(1, "orange", results)).start();
new Thread(new Task(2, "yellow", results)).start();
new Thread(new Task(3, "green", results)).start();
new Thread(new Task(4, "blue", results)).start();
new Thread(new Task(5, "indigo", results)).start();
new Thread(new Task(6, "violet", results)).start();
}
}
class Results {
private List<String> results = new ArrayList<String>();
private int i = 0;
public synchronized void submit(int order, String result) {
while (results.size() <= order) results.add(null);
results.set(order, result);
while ((i < results.size()) && (results.get(i) != null)) {
System.out.println("result delivered: " + i + " " + results.get(i));
++i;
}
}
}
class Task implements Runnable {
private final int order;
private final String result;
private final Results results;
public Task(int order, String result, Results results) {
this.order = order;
this.result = result;
this.results = results;
}
public void run() {
try {
Thread.sleep(Math.abs(result.hashCode() % 1000)); // simulate a long-running computation
}
catch (InterruptedException e) {} // you'd want to think about what to do if interrupted
System.out.println("task finished: " + order + " " + result);
results.submit(order, result);
}
}
If you need that fine-grained control, you should not use threads but instead look into using a suitable Executor with Callables or Runnables. See the Executors class for a wide selection.
A simple solution would be to use an array A of locks (one lock per thread). When thread i begins its executions, it acquires its associated lock A[i]. When it's ready to merge its results, it releases its lock A[i] and waits for locks A[0], A[1], ..., A[i - 1] to be released; then it merges the results.
(In this context, thread i means the i-th launched thread)
I don't know what classes to use in Java, but it must be easy to implement. You can begin reading this.
If you have more questions, feel free to ask.
public static void main(String[] args) throws InterruptedException{
MyRunnable r = new MyRunnable();
Thread t1 = new Thread(r,"A");
Thread t2 = new Thread(r,"B");
Thread t3 = new Thread(r,"C");
t1.start();
Thread.sleep(1000);
t2.start();
Thread.sleep(1000);
t3.start();
}
Control of thread execution order may be implemented quite easily with the semaphores. The code attached is based on the ideas presented in Schildt's book on Java (The complete reference....).
// Based on the ideas presented in:
// Schildt H.: Java.The.Complete.Reference.9th.Edition.
import java.util.concurrent.Semaphore;
class Manager {
int n;
// Initially red on semaphores 2&3; green semaphore 1.
static Semaphore SemFirst = new Semaphore(1);
static Semaphore SemSecond = new Semaphore(0);
static Semaphore SemThird = new Semaphore(0);
void firstAction () {
try {
SemFirst.acquire();
} catch(InterruptedException e) {
System.out.println("Exception InterruptedException catched");
}
System.out.println("First: " );
System.out.println("-----> 111");
SemSecond.release();
}
void secondAction() {
try{
SemSecond.acquire();
} catch(InterruptedException e) {
System.out.println("Exception InterruptedException catched");
}
System.out.println("Second: ");
System.out.println("-----> 222");
SemThird.release();
}
void thirdAction() {
try{
SemThird.acquire();
} catch(InterruptedException e) {
System.out.println("Exception InterruptedException catched");
}
System.out.println("Third: ");
System.out.println("-----> 333");
SemFirst.release();
}
}
class Thread1 implements Runnable {
Manager q;
Thread1(Manager q) {
this.q = q;
new Thread(this, "Thread1").start();
}
public void run() {
q.firstAction();
}
}
class Thread2 implements Runnable {
Manager q;
Thread2(Manager q) {
this.q = q;
new Thread(this, "Thread2").start();
}
public void run() {
q.secondAction();
}
}
class Thread3 implements Runnable {
Manager q;
Thread3(Manager q) {
this.q = q;
new Thread(this, "Thread3").start();
}
public void run() {
q.thirdAction();
}
}
class ThreadOrder {
public static void main(String args[]) {
Manager q = new Manager();
new Thread3(q);
new Thread2(q);
new Thread1(q);
}
}
This can be done without using synchronized keyword and with the help of volatile keyword. Following is the code.
package threadOrderingVolatile;
public class Solution {
static volatile int counter = 0;
static int print = 1;
static char c = 'A';
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread[] ths = new Thread[4];
for (int i = 0; i < ths.length; i++) {
ths[i] = new Thread(new MyRunnable(i, ths.length));
ths[i].start();
}
}
static class MyRunnable implements Runnable {
final int thID;
final int total;
public MyRunnable(int id, int total) {
thID = id;
this.total = total;
}
#Override
public void run() {
while(true) {
if (thID == (counter%total)) {
System.out.println("thread " + thID + " prints " + c);
if(c=='Z'){
c='A';
}else{
c=(char)((int)c+1);
}
System.out.println("thread " + thID + " prints " + print++);
counter++;
} else {
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// log it
}
}
}
}
}
}
Following is the github link which has a readme, that gives detailed explanation about how it happens.
https://github.com/sankar4git/volatile_thread_ordering

Categories