Increments and decrements in multi threaded environment - java

I am trying the classic increment/decrement of an int variable in a multi threaded environment. This is my sample code.
public class SyncIncDec {
public static void main(String[] args) {
SyncCounter count = new SyncCounter();
Thread incThread = new Thread(() -> {
count.increment();
});
Thread decThread = new Thread(() -> {
count.decrement();
});
Thread displayThread = new Thread(() -> {
System.out.println("Count value : " + count.getX());
});
incThread.start();
decThread.start();
displayThread.start();
try {
incThread.join();
} catch (InterruptedException e) {
// e.printStackTrace();
}
try {
decThread.join();
} catch (InterruptedException e) {
// e.printStackTrace();
}
try {
displayThread.join();
} catch (InterruptedException e) {
// e.printStackTrace();
}
}
}
class SyncCounter {
private int x=0;
public SyncCounter() {
super();
}
public SyncCounter(int y) {
super();
x = y ;
}
synchronized int getX() {
return x;
}
void setX(int y) {
x = y ;
}
void increment() {
++x;
}
void decrement() {
--x;
}
}
Though I have used join() method for all the three threads, I still get inconsistent results.
Doesn't join here mean for the main thread to wait until each of the thread has completed its execution? I even tried adding synchronized to each of three method signatures; yet I get inconsistent results.
Apart from using Atomic version of the variable, how else can I ensure that I get 0 always?

You invoke join() on the three threads only after all threads were started. So you don't have the guarantee that the thread referenced by the displayThread variable be run after the threads that increment and decrement the counter.
To ensure that, invoke join() on these threads after you started them :
incThread.start();
decThread.start();
incThread.join();
decThread.join();
displayThread.start();
It will block the current thread until incrementing and decrementing is performed and whatever the order as join() were invoked after the start() invocation of these threads.

Your SyncCounter is not thread safe at all. Mutable methods increment and decrement should be synchronized. Now days correct way to implement such a class would be in atomic orations.
For example:
class SyncCounter {
private final AtomicInteger x;
public SyncCounter() {
this(0);
}
public SyncCounter(int x) {
this.x = new AtomicInteger(x);
}
int getX() {
return x.get();
}
void setX(int x) {
this.x.set(x);
}
int increment() {
return x.incrementAndGet();
}
int decrement() {
return x.decrementAndGet();
}
}
And the test code:
final Thread incThread = new Thread(() -> {
count.increment();
});
final Thread decThread = new Thread(() -> {
count.decrement();
});
Thread displayThread = new Thread(() -> {
incThread.join();
decThread.join();
System.out.println("Count value : " + count.getX());
});

Though I have used join() method for all the three threads, I still get inconsistent results. Doesn't join here mean for the main thread to wait until each of the thread has completed its execution?
You have 2 problems going on in your code.
In your SyncCounter class, only the getX() method is synchronized. Because you have 3 threads sharing the same instance of this class, any method that is reading or updating the shared fields needs to be synchronized. This means the increment() and decrement() method need to also be synchronized. As mentioned by #Victor, replacing the SyncCounter with an AtomicInteger is an easy solution although I suspect your exercise needs to do it by hand.
...
synchronized int increment() {
...
synchronized int decrement() {
In your thread model, you have a race condition between the increment and decrement threads, and the display thread. Just because you start the display thread after the others doesn't mean that it runs last. It could be that the display thread finishes first in which case it would print 0 or it could print -1 or 1 depending on the race conditions. The easiest solution here is to have the main thread join with the increment and decrement threads and then it prints out the result.
// start the inc and dec threads running in the background
incThread.start();
decThread.start();
// wait for inc thread to finish
incThread.join();
// wait for dec thread to finish
decThread.join();
// now we can print out the value of the counter
System.out.println("Count value : " + count.getX());
If you must have a display thread then it should be started after
the joins of the increment and decrement threads like #davidxxx
recommends.
// start the inc and dec threads running in the background
incThread.start();
decThread.start();
// wait for inc thread to finish
incThread.join();
// wait for dec thread to finish
decThread.join();
// now start the display thread now that the increment/decrement is done
displayThread.start();
// wait for the display thread to finish
displayThread.join();

Related

Java code - Threads blocking each other

I am new to multithreading. I am trying to write a program where I have two threads. One thread prints odd number and then gives up the monitor lock using wait() and similarly other thread prints the even number and gives up the lock after printing the number
I have got 4 classes
Odd.java (print odd numbers between 1-100)
Even.java(print even number between 1-100)
SomeMaths.java( has got logic for printing odd and even numbers )
OEApp.java (Main class that starts the threads)
Problem - My code works as expected most of the times i.e it print number 1 to 100 in order. Both the thread take turns. But I noticed that there is a bug.Sometimes the even thread gets scheduled first and gets below output
2 **********
1 ###############################
After that nothing gets printed, Looks like there is a deadlock situation. I am not able to figure out why. Please help me to understand this
public class SomeMaths {
public synchronized void printOdd(){
for( int i=1;i<=100;i++){
if(i%2 !=0) {
System.out.println(i + " ###############################");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
}
}
public synchronized void printEven(){
for(int i=1;i<=100;i++){
if(i%2 ==0){
System.out.println(i +" **********");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
}
}
}
public class Odd implements Runnable {
SomeMaths sm;
public Odd(SomeMaths sm){
this.sm = sm;
}
#Override
public void run(){
sm.printOdd();
}
}
public class Even extends Thread {
SomeMaths sm;
public Even(SomeMaths sm){
this.sm = sm;
}
#Override
public void run(){
sm.printEven();
}
}
public class OEApp {
public static void main(String[] args) {
SomeMaths sm = new SomeMaths();
Thread odd = new Thread(new Odd(sm));
Thread even = new Thread(new Even(sm));
odd.start();
even.start();
try {
odd.join();
even.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I believe it works this way:
Even thread starts, 1 is odd so it calls notify (notifying no one), then 2 is even so it prints a message and waits
Odd thread starts, 1 is odd so it prints a message and waits
There's no one to call notify so both threads wait forever
What is your purpose for using the synchronize keyword ?
It can only assure you that your function will not be running multiple times at the same time.
I assume that you want one thread to notify another ? Is that right ?
But what if the notify is called before the wait occurred ?
You know that you can use the debugger to see each thread, and thus know where each thread is stuck ?
Please keep in mind, once start is called, you can't know which thread will have cpu time.
Furthermore you are trying to synchronize two threads (by the use of the notify/wait mecanism), but there are other mecanisms that will be proved simpler (e.g. semaphore: each thread having it own semaphore, acquiring it own semaphore and releasing the other one semaphore; initialize each semaphore to 1 and it will go smoothly).
P.S. :
I am forced to post an answer, but it should be a comment; sorry
Why use both runnable and thread interface ? Furthermore your Even class is already a thread, so no use to wrap it once again.
See https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem

Java Threading - Simple wait() notify() issues [duplicate]

I have 2 matrices and I need to multiply them and then print the results of each cell. As soon as one cell is ready I need to print it, but for example I need to print the [0][0] cell before cell [2][0] even if the result of [2][0] is ready first. So I need to print it by order.
So my idea is to make the printer thread wait until the multiplyThread notifies it that the correct cell is ready to be printed and then the printerThread will print the cell and go back to waiting and so on..
So I have this thread that does the multiplication:
public void run()
{
int countNumOfActions = 0; // How many multiplications have we done
int maxActions = randomize(); // Maximum number of actions allowed
for (int i = 0; i < size; i++)
{
result[rowNum][colNum] = result[rowNum][colNum] + row[i] * col[i];
countNumOfActions++;
// Reached the number of allowed actions
if (countNumOfActions >= maxActions)
{
countNumOfActions = 0;
maxActions = randomize();
yield();
}
}
isFinished[rowNum][colNum] = true;
notify();
}
Thread that prints the result of each cell:
public void run()
{
int j = 0; // Columns counter
int i = 0; // Rows counter
System.out.println("The result matrix of the multiplication is:");
while (i < creator.getmThreads().length)
{
synchronized (this)
{
try
{
this.wait();
}
catch (InterruptedException e1)
{
}
}
if (creator.getmThreads()[i][j].getIsFinished()[i][j] == true)
{
if (j < creator.getmThreads()[i].length)
{
System.out.print(creator.getResult()[i][j] + " ");
j++;
}
else
{
System.out.println();
j = 0;
i++;
System.out.print(creator.getResult()[i][j] + " ");
}
}
}
Now it throws me these exceptions:
Exception in thread "Thread-9" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-6" Exception in thread "Thread-4" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-5" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-8" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-7" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-11" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-10" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-12" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
line 49 in multiplyThread is the "notify()"..I think I need to use the synchronized differently but I am not sure how.
If anyone can help this code to work I will really appreciate it.
To be able to call notify() you need to synchronize on the same object.
synchronized (someObject) {
someObject.wait();
}
/* different thread / object */
synchronized (someObject) {
someObject.notify();
}
While using the wait and notify or notifyAll methods in Java the following things must be remembered:
Use notifyAll instead of notify if you expect that more than one thread will be waiting for a lock.
The wait and notify methods must be called in a synchronized context. See the link for a more detailed explanation.
Always call the wait() method in a loop because if multiple threads are waiting for a lock and one of them got the lock and reset the condition, then the other threads need to check the condition after they wake up to see whether they need to wait again or can start processing.
Use the same object for calling wait() and notify() method; every object has its own lock so calling wait() on object A and notify() on object B will not make any sense.
Do you need to thread this at all ? I'm wondering how big your matrices are, and whether there's any benefit in having one thread print whilst the other does the multiplication.
Perhaps it would be worth measuring this time before doing the relatively complex threading work ?
If you do need to thread it, I would create 'n' threads to perform the multiplication of the cells (perhaps 'n' is the number of cores available to you), and then use the ExecutorService and Future mechanism to dispatch multiple multiplications simultaneously.
That way you can optimise the work based on the number of cores, and you're using the higher level Java threading tools (which should make life easier). Write the results back into a receiving matrix, and then simply print this once all your Future tasks have completed.
Let's say you have 'black box' application with some class named BlackBoxClass that has method doSomething();.
Further, you have observer or listener named onResponse(String resp) that will be called by BlackBoxClass after unknown time.
The flow is simple:
private String mResponse = null;
...
BlackBoxClass bbc = new BlackBoxClass();
bbc.doSomething();
...
#override
public void onResponse(String resp){
mResponse = resp;
}
Lets say we don't know what is going on with BlackBoxClass and when we should get answer but you don't want to continue your code till you get answer or in other word get onResponse call. Here enters 'Synchronize helper':
public class SyncronizeObj {
public void doWait(long l){
synchronized(this){
try {
this.wait(l);
} catch(InterruptedException e) {
}
}
}
public void doNotify() {
synchronized(this) {
this.notify();
}
}
public void doWait() {
synchronized(this){
try {
this.wait();
} catch(InterruptedException e) {
}
}
}
}
Now we can implement what we want:
public class Demo {
private String mResponse = null;
...
SyncronizeObj sync = new SyncronizeObj();
public void impl(){
BlackBoxClass bbc = new BlackBoxClass();
bbc.doSomething();
if(mResponse == null){
sync.doWait();
}
/** at this momoent you sure that you got response from BlackBoxClass because
onResponse method released your 'wait'. In other cases if you don't want wait too
long (for example wait data from socket) you can use doWait(time)
*/
...
}
#override
public void onResponse(String resp){
mResponse = resp;
sync.doNotify();
}
}
You can only call notify on objects where you own their monitor. So you need something like
synchronized(threadObject)
{
threadObject.notify();
}
notify() needs to be synchronized as well
I'll right simple example show you the right way to use wait and notify in Java.
So I'll create two class named ThreadA & ThreadB. ThreadA will call ThreadB.
public class ThreadA {
public static void main(String[] args){
ThreadB b = new ThreadB();//<----Create Instance for seconde class
b.start();//<--------------------Launch thread
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();//<-------------WAIT until the finish thread for class B finish
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + b.total);
}
}
}
and for Class ThreadB:
class ThreadB extends Thread{
int total;
#Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
notify();//<----------------Notify the class wich wait until my finish
//and tell that I'm finish
}
}
}
Simple use if you want How to execute threads alternatively :-
public class MyThread {
public static void main(String[] args) {
final Object lock = new Object();
new Thread(() -> {
try {
synchronized (lock) {
for (int i = 0; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + ":" + "A");
lock.notify();
lock.wait();
}
}
} catch (Exception e) {}
}, "T1").start();
new Thread(() -> {
try {
synchronized (lock) {
for (int i = 0; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + ":" + "B");
lock.notify();
lock.wait();
}
}
} catch (Exception e) {}
}, "T2").start();
}
}
response :-
T1:A
T2:B
T1:A
T2:B
T1:A
T2:B
T1:A
T2:B
T1:A
T2:B
T1:A
T2:B
we can call notify to resume the execution of waiting objects as
public synchronized void guardedJoy() {
// This guard only loops once for each special event, which may not
// be the event we're waiting for.
while(!joy) {
try {
wait();
} catch (InterruptedException e) {}
}
System.out.println("Joy and efficiency have been achieved!");
}
resume this by invoking notify on another object of same class
public synchronized notifyJoy() {
joy = true;
notifyAll();
}
For this particular problem, why not store up your various results in variables and then when the last of your thread is processed you can print in whatever format you want. This is especially useful if you are gonna be using your work history in other projects.
This looks like a situation for producer-consumer pattern. If you’re using java 5 or up, you may consider using blocking queue(java.util.concurrent.BlockingQueue) and leave the thread coordination work to the underlying framework/api implementation.
See the example from
java 5:
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html
or java 7 (same example):
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html
You have properly guarded your code block when you call wait() method by using synchronized(this).
But you have not taken same precaution when you call notify() method without using guarded block : synchronized(this) or synchronized(someObject)
If you refer to oracle documentation page on Object class, which contains wait() ,notify(), notifyAll() methods, you can see below precaution in all these three methods
This method should only be called by a thread that is the owner of this object's monitor
Many things have been changed in last 7 years and let's have look into other alternatives to synchronized in below SE questions:
Why use a ReentrantLock if one can use synchronized(this)?
Synchronization vs Lock
Avoid synchronized(this) in Java?

Two threads, two synchronized blocks and one intrinsic lock

I wrote a code snippet that starts two threads; one thread prints all odd numbers while another thread prints all even numbers.
I used a combination of intrinsic lock and thread communication commands to achieve proper interleaving of my two threads.
Here is my code,
public class threadEvenOdd implements Runnable
{
static Boolean isOdd=true;
int count = 10;
Boolean value;
static int c=1;
static Object lock = new Object();
threadEvenOdd(Boolean temp)
{
value = temp;
}
public void run()
{
if(value)
{
printOdd(count);
}
if(!value)
{
printEven(count);
}
}
void printOdd(int count)
{
try
{
for(int i=0;i<count/2;i++)
{
//System.out.println("odd enters lock");
synchronized(lock)
{
if(!isOdd)
{
//System.out.println("odd in barrier");
lock.wait();
}
System.out.println(c);
c++;
isOdd = false;
//System.out.println("odd notifies");
lock.notify();
}
}
}
catch(Exception e)
{
System.out.println(e);
}
}
void printEven(int count)
{
try
{
for(int i=0;i<count/2;i++)
{
//System.out.println("even enters lock");
synchronized(lock)
{
if(isOdd)
{
//System.out.println("even in barrier");
lock.wait();
}
System.out.println(c);
c++;
isOdd = true;
//System.out.println("even notifies");
lock.notify();
}
}
}
catch(Exception e)
{
System.out.println(e);
}
}
public static void main (String args[])
{
threadEvenOdd th1 = new threadEvenOdd(true);
threadEvenOdd th2 = new threadEvenOdd(false);
Thread t1 = new Thread(th1);
t1.setName("odd");
Thread t2 = new Thread(th2);
t2.setName("even");
//System.out.println(t1.getName() + " starts");
t1.start();
//System.out.println(t2.getName() + " starts");
t2.start();
}
}
Here are my questions:
The odd thread executes in the printOdd() function, while the even thread executes in the printEven() function. I am using one intrinsic lock for both threads; I don't understand how the two threads can exist in their respective synchronized blocks at the same time, because the use the same lock.
I removed the thread communication statements(notify, wait) from my code and still I obtained my desired output. I am now wondering if my code actually needs the thread communication statements at all.
I guess I still need to work on my understanding of multithreading concepts, as I am struggling to understand my own code :p Can anyone explain if there is a better way to do this using only the multithreading concepts that I have used?
Each thread has its own path of execution through the code. Even if two threads run the exact same code they still have two distinct execution points through the code execution through the code. When a thread reaches a synchronized statement it waits for the lock to be available - it will enter the synchronized block only if no other thread is inside a synchronized block guarded by the same lock.
You keep getting the same output although you removed the notify/wait statements can be coincidental. Did you try this with a relatively large value of the count field?
It is kind of hard to answer this question at the moment as you didn't specify what output do you expect this program to produce. Is "1,3,5,7,9,2,4,6,8" a valid output? Is "1,3,2,4,6,5,7,9,8"? Or is "1,2,3,4,5,6,7,8,9" the only valid output? That said, here a few quick points:
Use notifyAll() instead of notify
Minimize the state that is shared between threads. In this case, you share both isOdd and c. Note that the former can be computed from the latter via c % 2 == 1. Thus you can have the thread computing oddness instead of maintaining it as a piece of shared data.
Instead of sharing via static fields create an object (with instance fields) and pass this object to the constructor of each thread. Then you can use the object itself as a lock.
Here's how it can look like:
class SharedData {
int c;
boolean isOdd;
}
class ThreadEvenOdd {
SharedData sharedData;
public ThreadEvenOdd(SharedData sd) { this.sharedData = sd }
// ...
void printOdd(int count) {
try {
for(int i=0;i<count/2;i++) {
synchronized(sharedData) {
if(!sharedData.isOdd) { ... }
System.out.println(sharedData.c);
sharedData.c++;
sharedData.isOdd = false;
lock.notify();
}
}
}
catch(Exception e) {
System.out.println(e);
}
}
}
The nice thing about it is that you can then start defining real methods on sharedData (such as: a method that increases c and set isOdd to the appropriate value based on the value of c thus further simplifying the code in the thread class - and making the synchronization/notification less interleaved with the processing of the data, which makes the code more readable and less prone to errors.

java - wait and notify in a non-synchronized block

Sorry for my bad formatting. I am using a notepad to write my programs.
This is a working code. The only question I have is, I have read that notify and wait must be used in a Synchornized block. However, in the following example, wait and notify are not used in a synchronized block and still no error is thrown.
class counthrd implements Runnable {
Thread thrd;
String x;
counthrd cnt1;
counthrd() {
}
boolean suspended;
boolean stopped;
counthrd(String s, counthrd cnt1) {
thrd = new Thread(this, s);
this.cnt1 = cnt1;
thrd.start();
x = s;
}
public void run() {
try {
System.out.println("Starting " + thrd.currentThread().getName());
for (int i = 1; i < 100; i++) {
System.out.print(i + " ");
if ((i % 10) == 0) {
System.out.println();
Thread.sleep(500);
}
//synchronized(cnt1){
while (suspended) {
System.out.println("going to wait mode");
wait();
notify();
}
//}
}
} catch (Exception e) {
System.out.println(e);
}
}
synchronized void suspendme() {
suspended = true;
notify();
}
synchronized void resumeme() {
suspended = false;
notify();
}
}
class counter {
public static void main(String args[]) throws InterruptedException {
counthrd cnt1 = new counthrd();
counthrd cnthrd1 = new counthrd("thrd 1", cnt1);
Thread.sleep(1000);
System.out.println("going to wait mode");
cnt1.suspendme();
Thread.sleep(1000);
System.out.println("resuming");
cnt1.resumeme();
Thread.sleep(1000);
}
}
See my comment. Since IllegalMonitorStateException is never thrown, we know that wait is never being called.
Notice you have two instances of counthrd...
counthrd cnt1 = new counthrd();
counthrd cnthrd1 = new counthrd("thrd 1", cnt1);
See which instance you're calling suspendme and resumeme on?
Thread.sleep(1000);
System.out.println("going to wait mode");
cnt1.suspendme();
Thread.sleep(1000);
System.out.println("resuming");
cnt1.resumeme();
Thread.sleep(1000);
cnt1 is initialized using your no-arg constructor, seen here:
counthrd() {
}
The point is that cnt1 never actually starts its own thread. It never does anything, really. cnthrd1 is the one that starts a thread, as seen here:
counthrd(String s, counthrd cnt1) {
thrd = new Thread(this, s);
this.cnt1 = cnt1;
thrd.start();
x = s;
}
The point to make is that suspended is an instance field, and not shared between cnt1 and cnthrd1. Modifying cnt1.suspended will not cause cnthrd1 to go into "wait mode". wait is never called, and thus the exception is never thrown.
To demonstrate, try calling suspendme and resumeme on cnthrd1, instead... :-)
C:\dev\scrap>javac counter.java
C:\dev\scrap>java counter
Starting thrd 1
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
going to wait mode
going to wait mode
java.lang.IllegalMonitorStateException
resuming
That being said, I figured I'd suggest you do some stuff that your code should be doing.
Declare suspended as volatile. Without some explicit memory ordering guarantees, there's no guarantee when or even if cnthrd1 reads the updated value of suspended.
Ditch the cnt1 field and instance; there's no reason for them. Get rid of that empty constructor, too.
Thread.currentThread is a static method; you don't need to use an instance for it. That all aside, thrd is guaranteed to equal Thread.currentThread here.
counthrd.x is equal to thrd.getName; why not just use x instead?
Use some better, more descriptive names. For example, instead of x, why not name? Instead of thrd, why not thread? Instead of counthrd, why not CountingThread?
You only need to call notify in resumeme, not suspendme. (in fact, calling notify in suspendme could accidentally trigger an InterruptedException if the thread is sleeping i.e. when (i % 10) == 0)
You also don't want notify in the while (suspended) loop. Your while loop can actually be turned into an if statement, too, now.
As previously stated, you need synchronized (this) around your code that calls while.
Avoid doing real logic in the constructor, e.g. thrd.start().
suspend doesn't need to be synchronized. resume doesn't need to be synchronized, either; only the wait and notify calls require it.
You can find a modified version of your example that works properly here.

Thread Synchronization - How to execute threads alternatively

I have been trying to solve a problem involving thread communication using wait() and notify(). Basically i have 2 threads T1 and T2 and i want them to be executed in the following order
T1 , T2, T1, T2 ..... How can i achieve that?
Actual Problem: There are 2 threads T1 - which prints odd numbers (say 1 - 100) and T2 - which prints even numbers (1 - 100). Now, the output should be 1, 2, 3, 4 , 5 , .... 100
You describe a Producer-Consumer pattern.
It's java implementations described in numerous java books including M.Grand "Patterns in Java. Volume I" and "Java 2: The Complete Reference" by Naughton and Schildt.
Basic idea: both threads should use 1 monitor (i.e. their code should be inside synchronized(monitor) {} blocks). You also need some flag variable which should indicate which of two threads should work at the moment.
When one of your threads is inside synchronized block it should check flag variable whether it's his turn to do the job. If yes, let it work and then change flag value and then notify all waiting threads. If no, then it should wait.
Look at the java.util.concurrent package, specifically the Exchanger
You're trying to parallelize a multistep process right? If so, see my answer here for an approach and some working code to do that. The answer involves an ExecutorService (or two) and one or more work queues.
For this approach, your processing needs to be able to fit into a Runnable, along with intermediate state information for the processing. You feed each step to the ExecutorService as a Runnable, which will add a second Runnable to perform the next step. This maintains the order of execution, but lets you effectively run as many threads as you wish in parallel.
:EDIT:
As another has suggested, the Exchanger library class can be used for this if you explicitly want to limit processing to 2 threads. I prefer the above approach because it maintains order of execution and allows you to use the modern 4-core (and 8-core) systems fully. It should also reduce synchronization a bit.
If T1 and T2 are 2 different implementations of the Runnable interface, with T1 being a thread that prints just odd numbers (1,3,...) and T2 being one that prints even number (1,2.....), this can be done by using the wait() and notify() methods on a shared monitor. The important thing is for each thread to check for a shared flag before printing its value. The below code works;
//The shared monitor
public class Mutex {
public static boolean oddFlag;
}
//The Thread that is supposed to print Odd numbers (assuming an upper limit of 99)
public class OddPrinter implements Runnable {
private Mutex mutex;
public OddPrinter(Mutex mutex) {
this.mutex = mutex;
}
public synchronized void run() {
System.out.println("Started Thread: OddPrinter");
int i;
for(i=1; i<100; i+=2 ) {
synchronized (mutex) {
while(!Mutex.oddFlag) {
try {
mutex.wait();
} catch (InterruptedException ie) {
Thread.currentThread().interrupted();
}
}
if(Mutex.oddFlag == true) {
System.out.println("Print from OddPrinter: "+i);
Mutex.oddFlag = false;
mutex.notify();
}
}
}
System.out.println("Finished Thread: OddPrinter: "+i);
}
}
//The Thread that is supposed to print Odd numbers (assuming an upper limit of 98)
public class EvenPrinter implements Runnable {
private Mutex mutex;
public EvenPrinter(Mutex mutex) {
this.mutex = mutex;
}
public synchronized void run() {
System.out.println("Started Thread: EvenPrinter");
int i;
for(i=2; i<100; i+=2) {
synchronized (mutex) {
while(Mutex.oddFlag) {
try {
mutex.wait();
} catch (InterruptedException ie) {
Thread.currentThread().interrupted();
}
}
if(!(Mutex.oddFlag == true)) {
System.out.println("Print from EvenPrinter: "+i);
Mutex.oddFlag = true;
mutex.notify();
}
}
}
System.out.println("Finished Thread: EvenPrinter: "+i);
}
}
//The test harness that executes the threads
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class NumberPrinterTest {
public static void main(String[] args) throws Exception{
ExecutorService es = Executors.newFixedThreadPool(2);
Mutex mutex = new Mutex();
OddPrinter op = new OddPrinter(mutex);
EvenPrinter ep = new EvenPrinter(mutex);
Mutex.oddFlag = true;
es.execute(op);
es.execute(ep);
if(null != es){
es.shutdown();
try {
es.awaitTermination(1, TimeUnit.MINUTES);
} catch (InterruptedException e) {
Thread.currentThread().interrupted();
}
}
}
}

Categories