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
Related
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.
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();
}
}
I trying to use Synchronized methods, but I faced some interesting behavior such as:
I have three threads ThreadA - that invokes Increment method, ThreadB that invokes Decrement method and ThreadC that print current value;
But some values look incorrect:
debug:
Preparing threads
false
1
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0....
when it's supposed to have all 0 and 1 or other values;
My code is below:
package concurrency;
public class Synchronization {
public static void main(String[] args) throws InterruptedException {
System.out.println("Preparing threads");
Counter cnt = new Counter();
Thread threadA = new Thread(new ThreadA(cnt));
Thread threadB = new Thread(new ThreadB(cnt));
Thread ThreadC = new Thread (new ThreadC(cnt));
threadA.start();
threadB.start();
ThreadC.start();
}
private static class ThreadA implements Runnable {
private final Counter counter;
public ThreadA(Counter cnt) {
counter = cnt;
}
#Override
public void run() {
Thread.currentThread().setName("ThreadA");
System.out.println(((Boolean)
Thread.currentThread().isInterrupted()).toString());
try {
while (!Thread.currentThread().isInterrupted()) {
counter.Increment();
Thread.sleep(1000);
}
} catch (InterruptedException ex) {
System.out.println("InterruptedException ThreadA");
}
System.out.println("ThreadA finished");
}
}
private static class ThreadB implements Runnable {
private final Counter counter;
public ThreadB(Counter cnt) {
counter = cnt;
}
#Override
public void run() {
Thread.currentThread().setName("ThreadB");
try {
while (true) {
if (Thread.currentThread().isInterrupted()) {
break;
}
counter.Decrement();
Thread.sleep(1000);
}
} catch (InterruptedException ex) {
System.out.println("InterruptedExcepion threadB");
}
System.out.println("ThreadB Finished");
}
}
private static class ThreadC implements Runnable {
private final Counter counter;
public ThreadC(Counter cnt) {
counter = cnt;
}
#Override
public void run() {
Thread.currentThread().setName("ThreadC");
try {
while (true) {
if (Thread.currentThread().isInterrupted()) {
break;
}
System.out.println(counter.getValue());
Thread.sleep(1000);
}
} catch (InterruptedException ex) {
System.out.println("InterruptedExcepion threadB");
}
System.out.println("ThreadB Finished");
}
}
private static class Counter {
private int value = 0;
public synchronized void Increment() {
value++;
}
public synchronized void Decrement() {
value--;
}
public synchronized int getValue() {
return value;
}
}
}
I don't know what you see here that is unexpected. This code has 3 threads using a common shared counter. There is sufficient synchronization to make sure threads don't modify the shared data in an invalid way or see stale values. But the output will vary depending on which threads get more CPU time when. There is no requirement that these threads run in any particular order, what threads run and who gets the lock may seem arbitrary. The output from this is going to be unpredictable.
Java Thread - i want to generate numbers in sequence eg: 1,2,3,4... (there will be 2 threads only ) 1st thread o/p will be 1 ,second thread o/p will be 2 , again 1st thread o/p will be 3 and so on , it can be upto 10 or upto n number whatever just wanna get the logic please help me guys :|
below is my attempt to do it but its not working i know there would be wait() and notify() methods for sure but cant figure out the proper way to use them !
class NumberGenerator
{
static int number = 0;
synchronized public int numGenerator()
{
for(int i=0;i<20;i++)
{
System.out.println(i);
number=i;
}
return number;
}
}
class FirstThreadClass extends Thread
{
NumberGenerator num;
FirstThreadClass(NumberGenerator num)
{
this.num = num;
}
public void run()
{
System.out.println("i am from 1st thread :"+num.numGenerator());
}
}
class SecondThreadClass extends Thread
{
NumberGenerator num;
SecondThreadClass(NumberGenerator num)
{
this.num = num;
}
public void run()
{
System.out.println("i am from 2nd thread :"+num.numGenerator());
}
}
public class ThreadTesting {
public static void main(String[] args) {
FirstThreadClass ftc = new FirstThreadClass(new NumberGenerator());
SecondThreadClass stc = new SecondThreadClass(new NumberGenerator());
ftc.start();
stc.start();
}
}
class NumberGenerator
{
static int counter = 0;
public synchronized int getNextNumber()
{
return counter++;
}
}
class FirstThreadClass
extends Thread
{
NumberGenerator num;
FirstThreadClass(NumberGenerator num)
{
this.num = num;
}
public void run()
{
System.out.println("i am from 1st thread :" + num.getNextNumber());
}
}
class SecondThreadClass
extends Thread
{
NumberGenerator num;
SecondThreadClass(NumberGenerator num)
{
this.num = num;
}
public void run()
{
System.out.println("i am from 2nd thread :" + num.getNextNumber());
}
}
public class ThreadTesting
{
public static void main(String[] args)
{
FirstThreadClass ftc = new FirstThreadClass(new NumberGenerator());
SecondThreadClass stc = new SecondThreadClass(new NumberGenerator());
for (int k = 0; k < 10; k++)
{
ftc.run();
stc.run();
}
}
}
You can have each thread generate numbers as follows:
Thread 1: 1, 3, 5, 7, 9, ...
Thread 2: 2, 4, 6, 8, 10, ...
add to a concurrent collection and sort afterwards.
Do they have to generate only one each time, or is it ok if thread1 generate 2 numbers, then thread 2 generates 1 number etc... ?
Use a static int field that will act as a counter, and access it in a synchronized way.
static int counter = 0;
public synchronized int getNextNumber(){
return counter++;
}
Then the threads do :
while(...whatever..){
System.out.print(getNextNumber());
}
you can achieve this using cyclic barrier, create a barrier and once two threads have generated one number each print the two numbers
class ThreadTest {
private CyclicBarrier cyclicBarrier = new CyclicBarrier(2, new Runnable() {
#Override
public void run() {
System.out.println(oddNumberGenerator.result);
System.out.println(evenNumberGenerator.result);
}
});
private NumberGenerator oddNumberGenerator = new NumberGenerator(1,11,2);
private NumberGenerator evenNumberGenerator = new NumberGenerator(2,10,2);
public void generateSeries(){
oddNumberGenerator.generateNumbers();
evenNumberGenerator.generateNumbers();
}
class NumberGenerator {
private Thread thread;
private int result;
private NumberGenerator(final int initialValue, final int maxValue,
final int stepSize) {
this.thread = new Thread(new Runnable() {
#Override
public void run() {
for (int i = initialValue; i <= maxValue; i = i + stepSize) {
try {
result = i;
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
});
}
public void generateNumbers() {
thread.start();
}
}
main(String[] args){
new ThreadTest().generateSeries();
}
}
You can achieve using wait and notifyAll() . But it is always better to use standard java concurrent classes to achieve it
public class PrintAlternateValues {
public static void main(String[] args) {
final NumberValue number = new NumberValue();
final Object lockObject = new Object();
new Thread(){
private NumberValue n = number;
#Override
public void run() {
synchronized (lockObject) {
while(n.getValue() < n.getEndPoint()){
while(n.isToggle()){
try{
lockObject.wait();
}catch(Exception e){
e.printStackTrace();
}
}
n.incrementValue();
System.out.println(getName() + " printing "+n.getValue());
n.setToggle(true);
lockObject.notifyAll();
}
}
}
}.start();
new Thread(){
private NumberValue n = number;
#Override
public void run() {
synchronized (lockObject) {
while(n.getValue() < n.getEndPoint()){
while(!n.isToggle()){
try{
lockObject.wait();
}catch(Exception e){
e.printStackTrace();
}
}
n.incrementValue();
System.out.println(getName() + " printing "+n.getValue());
n.setToggle(false);
lockObject.notifyAll();
}
}
}
}.start();
}
}
class NumberValue {
private int value;
private boolean toggle = true;
private int endPoint = 10;
public int getEndPoint() {
return endPoint;
}
public void setEndPoint(int endPoint) {
this.endPoint = endPoint;
}
public boolean isToggle() {
return toggle;
}
public void setToggle(boolean toggle) {
this.toggle = toggle;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public synchronized void incrementValue(){
this.value++;
}
}
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