I came across a Java problem about multi-threaded programming (please see the code below). Based on this question and answer on StackOverflow, I think I understand why there could be a deadlock. But what I don't understand was if the program works correctly (i.e. there is no deadlock), what would be the value of foo printed? I thought it would be 20 (thread1 counting up to 10 and thread2 counting up to 10 more). Could someone help me explain how this might (preferably in a simple way because I'm still new to thread programming)? Thank you.
public class ThreadTest{
private static class ThreadOne extends Thread{
private ThreadTwo threadTwo;
public int foo = 0;
public void setThreadTwo(ThreadTwo th){
threadTwo = th;
}
public void run(){
try{
for(int i=0;i<10;i++) foo += i;
synchronized(this){this.notify();};
synchronized(threadTwo){threadTwo.wait();};
System.out.print("Foo: " + threadTwo.foo);
}catch(InterruptedException e){ e.printStackTrace();}
}
}
private static class ThreadTwo extends Thread{
private final ThreadOne threadOne;
public int foo = 0;
public ThreadTwo(ThreadOne th){
threadOne = th;
}
public void Run(){
try{
synchronized(threadOne){threadOne.wait();}
foo = threadOne.foo;
for(int i=0;i<10;i++) foo += i;
synchronized(this){this.notify();};
}
catch(InterruptedException e){e.printStackTrace();}
}
}
public static void main(){
ThreadOne th1 = new ThreadOne();
ThreadTwo th2 = new ThreadTwo(th1);
th1.setThreadTwo(th2);
th1.start(); th2.start();
th1.join(); th2.join();
}
}
According to your code and without deadlocks foo value will be 90 (if i didn't miscalculate). Because instead of foo += 1 you did foo += i.
EDIT: Okay, step by step.
foo = 0
th1 and th2 starts. th2 waits for notify. th1 increments foo up to 45
th1 notifies and starts to wait th2. th2 is notified and starts to increment foo from 45 to 90
th2 notifies th1. th1 is notified, and it prints th2.foo, which is 90
EDIT 2: Correct way to count from 0 to 90 from 2 threads without concurrent modification is something like this
public class ThreadTest {
private static int counter = 0;
private static class Thread1 extends Thread {
final Object lock;
public Thread1(Object lock) {
this.lock = lock;
}
#Override
public void run() {
synchronized (lock) {
for (int i = 0; i < 10; i++)
counter += i;
}
}
}
private static class Thread2 extends Thread {
final Object lock;
public Thread2(Object lock) {
this.lock = lock;
}
#Override
public void run() {
synchronized (lock) {
for (int i = 0; i < 10; i++)
counter += i;
}
}
}
public static void main(String[] args) {
final Object lock = new Object();
final Thread th1 = new Thread1(lock);
final Thread th2 = new Thread2(lock);
th1.start();
th2.start();
try {
th1.join();
th2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Counter: " + counter);
}
}
But if you are forced to use wait and notify, than it's a bit more complicated. Use object of this class as common lock instead of Object
class Locker {
private boolean isLocked = false;
public synchronized void lock() throws InterruptedException {
while (isLocked) wait();
isLocked = true;
}
public synchronized void unlock() {
isLocked = false;
notify();
}
}
And in run method us it like this:
#Override
public void run() {
try {
locker.lock();
for (int i = 0; i < 10; i++)
counter += i;
locker.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Related
I simply want to use thread to print out from 1 to 10. But my code will stop at number 1. input() will provide variable from 1 to 10, while output() will print out them. input() will be executed first and then output(). After that for() will make sure they will start another iteration.
class InputOutput{
private static int i=0;
private static boolean ToF=false;
synchronized void output(){
try{
while(!ToF){
notify();
wait();
}
}
catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Output: "+i);
ToF=false;
notify();
}
synchronized void input(){
try{
while(ToF){
notify();
wait();
}
}
catch(InterruptedException e){
e.printStackTrace();
}
i++;
ToF=true;
notify();
}
class input implements Runnable{
private int i=1;
InputOutput io=new InputOutput();
public void run(){
for(i=1;i<=10;i++)
io.input();
}
}
class output implements Runnable{
private int i=1;
InputOutput io=new InputOutput();
public void run(){
for(i=1;i<=10;i++)
io.output();
}
}
public class Homework07Part3 {
public static void main(String[] args) {
Thread t1=new Thread(new input());
t1.start();
Thread t2=new Thread(new output());
t2.start();
}
}
while loop you put wait on a single object for which two thread communication
while(ToF){
//dont put notify here.
notify();
wait();
}
Make it instance variable
private static boolean ToF=false;
public class Homework07Part3 {
public static void main(String[] args) {
InputOutput io = new InputOutput();
Thread t1 = new Thread(new input(io));
t1.start();
Thread t2 = new Thread(new output(io));
t2.start();
}
private static class input implements Runnable {
private int i = 1;
private InputOutput io;
public input(InputOutput io) {
this.io = io;
}
public void run() {
for (i = 1; i <= 10; i++)
io.input();
}
}
private static class output implements Runnable {
private int i = 1;
private InputOutput io;
public output(InputOutput io) {
this.io = io;
}
public void run() {
for (i = 1; i <= 10; i++)
io.output();
}
}
}
class InputOutput {
private int i = 0;
private boolean ToF = false;
synchronized void output() {
try {
while (!ToF) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Output: " + i);
ToF = false;
notify();
}
synchronized void input() {
try {
while (ToF) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
ToF = true;
notify();
}
}
I simply want to use thread to print out from 1 to 10. But my code will stop at number 1.
[[ The other answer seems to have fixed your problem but it doesn't explain what is happening and why the fix works. ]]
You problem is that both threads are calling synchronize and notify() and wait() on different objects. When threads communicate using these signals they both need to be sharing the same object instance. You are creating 2 InputOutput objects so both of your threads are stuck in wait() since the notify() calls are lost.
class Input implements Runnable{
...
// this is local to the Input class
InputOutput io=new InputOutput();
...
class Output implements Runnable{
...
// this is a different instance
InputOutput io=new InputOutput();
You should do something like the following:
final InputOutput io = new InputOutput();
Thread t1=new Thread(new Input(io));
t1.start();
Thread t2=new Thread(new Output());
t2.start();
...
private static class Input {
private final InputOutput io;
public Input(InputOutput io) { this.io = io; }
...
private static class Output {
private final InputOutput io;
public Output(InputOutput io) { this.io = io; }
...
So then both of your Input and Output classes are using the same instance of the InputOutput class. When they call synchronized on the methods, they are locking on the same instance and when they call wait() and notify() the signals are seen by the other thread.
Assume that one thread prints "Hello" and another prints "World". I have done it successfully for one time, as follows:
package threading;
public class InterThread {
public static void main(String[] args) {
MyThread mt=new MyThread();
mt.start();
synchronized(mt){
System.out.println("Hello");
try {
mt.wait();
i++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class MyThread extends Thread{
public void run(){
synchronized(this){
System.out.println("World!");
notify();
}
}
}
How do I do it for multiple time printing, say for 5 times? I tried putting for loop around the synchronized block, but of no use.
Here being two interdependent threads, we need two synchronizing objects. they could be one of many things. one integer, another object; one Boolean another object; both object; both semaphores and so on. the synchronization technique could be either Monitor or Semaphore any way you like, but they have to be two.
I have modified your code to use semaphore instead of Monitor. The Semaphore works more transparently. You can see the acquire and release happening. Monitors are even higher constructs. Hence Synchronized works under the hood.
If you are comfortable with the following code, then you can convert it to use Monitors instead.
import java.util.concurrent.Semaphore;
public class MainClass {
static Semaphore hello = new Semaphore(1);
static Semaphore world = new Semaphore(0);
public static void main(String[] args) throws InterruptedException {
MyThread mt=new MyThread();
mt.hello = hello;
mt.world = world;
mt.start();
for (int i=0; i<5; i++) {
hello.acquire(); //wait for it
System.out.println("Hello");
world.release(); //go say world
}
}
}
class MyThread extends Thread{
Semaphore hello, world;
public void run(){
try {
for(int i = 0; i<5; i++) {
world.acquire(); // wait-for it
System.out.println(" World!");
hello.release(); // go say hello
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadSeq {
Object hello = new Object();
Object world = new Object();
public static void main(String[] args) throws InterruptedException {
for(int i=0; i<6;i++){
Runnable helloTask = new Runnable(){
#Override
public void run(){
new ThreadSeq().printHello();
}
};
Runnable worldTask = new Runnable(){
#Override
public void run(){
new ThreadSeq().printWorld();
}
};
Thread t1 = new Thread(helloTask);
Thread t2 = new Thread(worldTask);
t1.start();
t1.join();
t2.start();
t2.join();
}
}
public void printHello(){
synchronized (hello) {
System.out.println("Hello");
}
}
public void printWorld(){
synchronized (world) {
System.out.println("World");
}
}
}
The goal here is to synchronize threads so that when one is done it notify the other. If I have to make it, it would be 2 threads executing the same code with different data. Each thread has its own data ("Hello" and true to T1, "World" and false to t2), and share a variable turn plus a separate lock object.
while(/* I need to play*/){
synchronized(lock){
if(turn == myturn){
System.out.println(mymessage);
turn = !turn; //switch turns
lock.signal();
}
else{
lock.wait();
}
}
}
Before you start trying to get it to work five times you need to make sure it works once!
Your code is not guaranteed to always print Hello World! - the main thread could be interrupted before taking the lock of mt (note that locking on thread objects is generally not a good idea).
MyThread mt=new MyThread();
mt.start();
\\ interrupted here
synchronized(mt){
...
One approach, that will generalise to doing this many times, is to use an atomic boolean
import java.util.concurrent.atomic.AtomicBoolean;
public class InterThread {
public static void main(String[] args) {
int sayThisManyTimes = 5;
AtomicBoolean saidHello = new AtomicBoolean(false);
MyThread mt=new MyThread(sayThisManyTimes,saidHello);
mt.start();
for(int i=0;i<sayThisManyTimes;i++){
while(saidHello.get()){} // spin doing nothing!
System.out.println("Hello ");
saidHello.set(true);
}
}
}
class MyThread extends Thread{
private final int sayThisManyTimes;
private final AtomicBoolean saidHello;
public MyThread(int say, AtomicBoolean said){
super("MyThread");
sayThisManyTimes = say;
saidHello = said;
}
public void run(){
for(int i=0;i<sayThisManyTimes;i++){
while(!saidHello.get()){} // spin doing nothing!
System.out.println("World!");
saidHello.set(false);
}
}
}
This is in C:
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t hello_lock, world_lock;
void printhello()
{
while(1) {
pthread_mutex_lock(&hello_lock);
printf("Hello ");
pthread_mutex_unlock(&world_lock);
}
}
void printworld()
{
while(1) {
pthread_mutex_lock(&world_lock);
printf("World ");
pthread_mutex_unlock(&hello_lock);
}
}
int main()
{
pthread_t helloThread, worldThread;
pthread_create(&helloThread,NULL,(void *)printhello,NULL);
pthread_create(&helloThread,NULL,(void *)printhello,NULL);
pthread_join(helloThread);
pthread_join(worldThread);
return 0;
}
There are two thread and both has its own data ("Hello" and true to ht, "World" and false to wt), and share a variable objturn.
public class HelloWorldBy2Thread {
public static void main(String[] args) {
PrintHelloWorld hw = new PrintHelloWorld();
HelloThread ht = new HelloThread(hw);
WorldThread wt = new WorldThread(hw);
ht.start();
wt.start();
}
}
public class HelloThread extends Thread {
private PrintHelloWorld phw;
private String hello;
public HelloThread(PrintHelloWorld hw) {
phw = hw;
hello = "Hello";
}
#Override
public void run(){
for(int i=0;i<10;i++)
phw.print(hello,true);
}
}
public class WorldThread extends Thread {
private PrintHelloWorld phw;
private String world;
public WorldThread(PrintHelloWorld hw) {
phw = hw;
world = "World";
}
#Override
public void run(){
for(int i=0;i<10;i++)
phw.print(world,false);
}
}
public class PrintHelloWorld {
private boolean objturn=true;
public synchronized void print(String str, boolean thturn){
while(objturn != thturn){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(str+" ");
objturn = ! thturn;
notify();
}
}
In simple way we can do this using wait() and notify() without creating any extra object.
public class MainHelloWorldThread {
public static void main(String[] args) {
HelloWorld helloWorld = new HelloWorld();
Thread t1 = new Thread(() -> {
try {
helloWorld.printHello();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(() -> {
try {
helloWorld.printWorld();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// printHello() will be called first
t1.setPriority(Thread.MAX_PRIORITY);
t1.start();
t2.start();
}
}
class HelloWorld {
public void printHello() throws InterruptedException {
synchronized (this) {
// Infinite loop
while (true) {
// Sleep for 500ms
Thread.sleep(500);
System.out.print("Hello ");
wait();
// This thread will wait to call notify() from printWorld()
notify();
// This notify() will release lock on printWorld() thread
}
}
}
public void printWorld() throws InterruptedException {
synchronized (this) {
// Infinite loop
while (true) {
// Sleep for 100ms
Thread.sleep(100);
System.out.println("World");
notify();
// This notify() will release lock on printHello() thread
wait();
// This thread will wait to call notify() from printHello()
}
}
}
}
I was given following code snippet:
public class ThreadTest{
private static class Thread01 extends Thread{
private Thread02 _th2;
public int foo = 0;
public void setThrd02(Thread02 thrd2){
_th2 = thrd2;
}
public void run(){
try{
for(int i=0;i<10;i++) foo += i;
synchronized(this){this.notify();};
synchronized(_th2){_th2.wait();};
System.out.print(" Foo: " + _th2.foo);
}catch(InterruptedException ie){ ie.printStackTrace();}
}
}
private static class Thread02 extends Thread{
private final Thread01 _th1;
public int foo = 0;
public Thread02(Thread01 th1){
_th1 = th1;
}
public void Run(){
try{
synchronized(_th1){_th1.wait();}
foo = _th1.foo;
for(int i=0;i<10;i++) foo += i;
synchronized(this){this.notify();};
}
catch(InterruptedException ie){ie.printStackTrace();}
}
}
public static void main(){
Thread01 th1 = new Thread01();
Thread02 th2 = new Thread02(th1);
th1.setThrd02(th2);
th1.start(); th2.start();
th1.join(); th2.join();
}
}
I think the assumption and corresponding purpose of the code is like
th2 run first, it is changed to waiting status by calling _th1.wait();
Then, th1 calculates foo and wake up th2, th1 goes into waiting status;
Th2 reads foo from thread1 and updated to 110, then wakes up th1 and th2 exit.
Then th1 exit.
The threads could be very risk because it is very possible that thread one runs first and thread 2 will wait forever.
I am not sure any other potential problems of the code.
One possible way that can fix the problem is, for example in the thread1
public class ThreadTest{
private static boolean updated = false;
private static boolean finished = false;
private static Thread01 extends Thread{
public void Run(){
// do calcuation
while(finished){
wait();
}
// output result
}
}
private static Thread02 extends Thread{
public void run(){
while(false){
wait();
}
foo = th1.foo;
// do calculation
// similar mechanism to notify thread 1
}
}
There is no guarantee of ordering in your threads. It's sufficient for Thread01 to go past
synchronized(this){this.notify();}; before Thread02 does synchronized(_th1){_th1.wait();} to have both threads waiting indefinitely.
Note: The fact that you are calling wait and notify on _th1 and _th2 is irrelevant. Threads here will be treated as any other object.
#Alex has already pointed out the problems with wait and notify not being called in the order the code expects them to be (+1). However, since this is an interview question there are several other things wrong with this code:
Horrible naming conventions and code formatting,
Public field accessors,
Synchronizing on a Thread object (bizarre),
Catching InterruptedException and then just exiting the Thread,
No exception handling,
(Personal preference) Not using the Java concurrency libraries.
I'm sure the question was posed to tie you in knots and figure out why the concurrency is broken but, IMHO, that code is so hideous i wouldn't even begin to debug it - i'd just throw it away.
Following can be a better fix
public class ThreadTest{
private static volatile boolean updated = false;
private static volatile boolean finished = false;
private static class Thread01 extends Thread{
private Thread02 _th2;
public int foo = 0;
public void setThread2(Thread02 th2){
_th2 = th2;
}
public void Run(){
for(int i=0;i<10;i++) foo += i;
System.out.print(" thread1 calcualtion " + foo + "\n");
try{
updated = true;
synchronized(this) {this.notify();};
synchronized(_th2){
while(!finished)
_th2.wait();
System.out.print("Foo: " + _th2.foo );
}
}
catch(InterruptedException ie){
ie.printStackTrace();
}
}
}
private static class Thread02 extends Thread{
private final Thread01 _th1;
public int foo = 0;
public Thread02(Thread01 th1){
_th1 = th1;
}
public void run(){
try{
synchronized(_th1){
while(!updated)
_th1.wait();
foo = _th1.foo;
}
for(int i=0;i<10;i++) foo +=i;
finished = true;
synchronized(this){ this.notify();}
}catch(InterruptedException ie){
ie.printStackTrace();
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread01 th1 = new Thread01();
Thread02 th2 = new Thread02(th1);
th1.setThread2(th2);
try{
th1.start();
th2.start();
th1.join();
th2.join();
}catch(InterruptedException ie){
ie.printStackTrace();
}
}
I have two threads thread1(printing numbers) & thread2(printing alphabets).
My goal is to have the following output via syncronization:
1
a
2
b
3
c
4
d
5
e
class thread1 implements Runnable {
public void run() {
try {
for (int i = 1; i <= 5; i++) {
System.out.println("Is Thread1 holding lock of Testing.class?:"+Thread.holdsLock(Testing.class));
synchronized (Testing.class) {
System.out.println("Is Thread1 holding lock of Testing.class?:"+Thread.holdsLock(Testing.class));
try {
System.out.println(i);
Testing.class.notifyAll();
System.out.println("Thread1:Going to wait");
Testing.class.wait();
System.out.println("Thread1:Resuming from wait");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("Finsihed thread1");
} catch (Exception e) {
System.out.println(e);
}
}
}
class thread2 implements Runnable {
char[] alphabets = { 'a', 'b', 'c', 'd', 'e' };
public void run() {
try {
for (int i = 0; i < 5; i++) {
System.out.println("Is Thread2 holding lock of Testing.class?:"+Thread.holdsLock(Testing.class));
synchronized (Testing.class) {
try {
System.out.println("Is Thread2 holding lock of Testing.class?:"+Thread.holdsLock(Testing.class));
System.out.println("Thread2:Going to wait");
Testing.class.wait();
System.out.println("Thread2:Resuming from wait");
System.out.println(alphabets[i]);
Testing.class.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} catch (Exception e) {
System.out.println(e);
}
}
}
public class Testing {
public static void main(String[] args) {
Testing w= new Testing();
thread1 t1 = new thread1();
thread2 t2 = new thread2();
Thread th1 = new Thread(t1, "");
Thread th2 = new Thread(t2, "");
try {
th1.start();
th2.start();
} catch (Exception e) {
System.out.println(e);
}
}
}
I am getting the output:
Is Thread1 holding lock of
Testing.class?:false
Is Thread1 holding lock of
Testing.class?:true
1
Thread1:Going to wait
Is Thread2 holding lock of
Testing.class?:false
Is Thread2 holding lock of
Testing.class?:true
Thread2:Going to wait
How did thread2 got hold the lock of Testing.class when it was already locked by thread1?. Also, Is there any other elegant way to achieve this sync?. Thanks in advance.
Read a bit more about Java Concurrency.
Calling wait releases the lock.
When you call the wait() method, the thread that you call it in is temporarily giving up the lock. So while thread1 is waiting inside the wait() method, it is not holding the lock, and thread2 can get the lock.
When the wait() method returns, the thread will hold the lock again.
The API documentation of the wait() method in class Object explains this in detail.
The basic problem you have is that you release the synchronized block allowing both threads to go through the loop at the same time. This means either thread can obtain the lock in any order.
AFAIK, The simplest solution is to use a flag.
final int length = 10;
final AtomicBoolean flag = new AtomicBoolean();
new Thread(new Runnable() {
public void run() {
for (int i=1;i<=length;i++) {
while(flag.get());
System.out.print(i+" ");
flag.set(true);
}
}
}).start();
new Thread(new Runnable() {
public void run() {
for (char c='a';c<'a'+length;c++) {
while(!flag.get());
System.out.print(c+" ");
flag.set(false);
}
System.out.println();
}
}).start();
The most elegant way to have this task done in sync is to have one thread. Threads are specificly designed to execute two tasks with as little dependence as possible between them.
BTW
If notifyAll() is called before wait() is called, the notify will be lost. wait() will wait forever.
You create a Testing object you discard (remove it).
You trap InterruptedException which you print and continue as if nothing happened (i.e. remove the nested catch)
This is the complete working code
public class MyClass
{
MyClass mClass;
public void doTest()
{
final int [] a = {1,2,3,4,5,6,7,8,9,10};
final char [] c = {'a','b','c','d','e','f','g','h','i','j'};
mClass = this;
Thread t1 = new Thread(new Runnable(){
public void run()
{
for(int i = 0 ; i<a.length ; i++)
{
synchronized(mClass)
{
System.out.print(a[i]+" ");
mClass.notify();
try{mClass.wait();}catch(Exception e){}
}
}
}
});
t1.start();
Thread t2 = new Thread(new Runnable(){
public void run()
{
for(int i = 0 ; i<c.length ; i++)
{synchronized(mClass)
{
System.out.print(c[i]+" ");
mClass.notify();
try{mClass.wait();}catch(Exception e){}
}
}
}
});
t2.start();
}
public static void main(String [] ar)
{
new MyClass().doTest();
}
}
public class MyClass
{
MyClass mClass;
boolean isFirstStartedRunning = true;
public void doTest()
{
final int [] a = {1,2,3,4,5,6,7,8,9,10};
final char [] c = {'a','b','c','d','e','f','g','h','i','j'};
mClass = this;
Thread t1 = new Thread(new Runnable(){
public void run()
{
isFirstStartedRunning = false;
for(int i = 0 ; i<a.length ; i++)
{
synchronized(mClass)
{
System.out.print(a[i]+" ");
mClass.notify();
if(i==a.length-1)return;
try{mClass.wait();}catch(Exception e){}
}
}
}
});
t1.start();
Thread t2 = new Thread(new Runnable(){
public void run()
{
if(isFirstStartedRunning){
try{mClass.wait();}catch(Exception e){}
}
for(int i = 0 ; i<c.length ; i++)
{
synchronized(mClass)
{
System.out.print(c[i]+" ");
mClass.notify();
if(i==a.length-1)return;
try{mClass.wait();}catch(Exception e){}
}
}
}
});
t2.start();
}
public static void main(String [] ar)
{
new MyClass().doTest();
}
}
check the answer now
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