Two threads, two synchronized blocks and one intrinsic lock - java

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.

Related

Increments and decrements in multi threaded environment

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();

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?

Assigning a object to a field defined outside a synchronized block - is it thread safe?

Is there anything wrong with the thread safety of this java code? Threads 1-10 add numbers via sample.add(), and Threads 11-20 call removeAndDouble() and print the results to stdout. I recall from the back of my mind that someone said that assigning item in same way as I've got in removeAndDouble() using it outside of the synchronized block may not be thread safe. That the compiler may optimize the instructions away so they occur out of sequence. Is that the case here? Is my removeAndDouble() method unsafe?
Is there anything else wrong from a concurrency perspective with this code? I am trying to get a better understanding of concurrency and the memory model with java (1.6 upwards).
import java.util.*;
import java.util.concurrent.*;
public class Sample {
private final List<Integer> list = new ArrayList<Integer>();
public void add(Integer o) {
synchronized (list) {
list.add(o);
list.notify();
}
}
public void waitUntilEmpty() {
synchronized (list) {
while (!list.isEmpty()) {
try {
list.wait(10000);
} catch (InterruptedException ex) { }
}
}
}
public void waitUntilNotEmpty() {
synchronized (list) {
while (list.isEmpty()) {
try {
list.wait(10000);
} catch (InterruptedException ex) { }
}
}
}
public Integer removeAndDouble() {
// item declared outside synchronized block
Integer item;
synchronized (list) {
waitUntilNotEmpty();
item = list.remove(0);
}
// Would this ever be anything but that from list.remove(0)?
return Integer.valueOf(item.intValue() * 2);
}
public static void main(String[] args) {
final Sample sample = new Sample();
for (int i = 0; i < 10; i++) {
Thread t = new Thread() {
public void run() {
while (true) {
System.out.println(getName()+" Found: " + sample.removeAndDouble());
}
}
};
t.setName("Consumer-"+i);
t.setDaemon(true);
t.start();
}
final ExecutorService producers = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
final int j = i * 10000;
Thread t = new Thread() {
public void run() {
for (int c = 0; c < 1000; c++) {
sample.add(j + c);
}
}
};
t.setName("Producer-"+i);
t.setDaemon(false);
producers.execute(t);
}
producers.shutdown();
try {
producers.awaitTermination(600, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
sample.waitUntilEmpty();
System.out.println("Done.");
}
}
It looks thread safe to me. Here is my reasoning.
Everytime you access list you do it synchronized. This is great. Even though you pull out a part of the list in item, that item is not accessed by multiple threads.
As long as you only access list while synchronized, you should be good (in your current design.)
Your synchronization is fine, and will not result in any out-of-order execution problems.
However, I do notice a few issues.
First, your waitUntilEmpty method would be much more timely if you add a list.notifyAll() after the list.remove(0) in removeAndDouble. This will eliminate an up-to 10 second delay in your wait(10000).
Second, your list.notify in add(Integer) should be a notifyAll, because notify only wakes one thread, and it may wake a thread that is waiting inside waitUntilEmpty instead of waitUntilNotEmpty.
Third, none of the above is terminal to your application's liveness, because you used bounded waits, but if you make the two above changes, your application will have better threaded performance (waitUntilEmpty) and the bounded waits become unnecessary and can become plain old no-arg waits.
Your code as-is is in fact thread safe. The reasoning behind this is two part.
The first is mutual exclusion. Your synchronization correctly ensures that only one thread at a time will modify the collections.
The second has to do with your concern about compiler reordering. Youre worried that the compile can in fact re order the assigning in which it wouldnt be thread safe. You dont have to worry about it in this case. Synchronizing on the list creates a happens-before relationship. All removes from the list happens-before the write to Integer item. This tells the compiler that it cannot re order the write to item in that method.
Your code is thread-safe, but not concurrent (as in parallel). As everything is accessed under a single mutual exclusion lock, you are serialising all access, in effect access to the structure is single-threaded.
If you require the functionality as described in your production code, the java.util.concurrent package already provides a BlockingQueue with (fixed size) array and (growable) linked list based implementations. These are very interesting to study for implementation ideas at the very least.

Thread Deadlock

I have 2 threads. One thread prints odd numbers and the second thread prints even numbers. Now, I have to execute the threads alternatively so that i can output 1,2,3,4,5,6,.....
I have written a program for this and this is resulting in a deadlock. Can someone explain what is the problem with the code and how to rectify it?
class BooleanObject {
boolean flag;
BooleanObject(boolean flag) {
this.flag = flag;
}
}
class EvenThread extends Thread {
Object lock;
BooleanObject flagObj;
EvenThread(Object o, BooleanObject flag) {
lock = o;
this.flagObj = flag;
}
public void run() {
for (int i=2;i<100;i+=2) {
synchronized(lock) {
if (flagObj.flag == false) {
flagObj.flag = true;
lock.notify();
}
else {
try {
while (flagObj.flag == true) {
lock.wait();
}
}
catch (InterruptedException e) {
}
}
System.out.println(i);
}
}
}
}
class OddThread extends Thread {
Object lock;
BooleanObject flagObj;
OddThread(Object o, BooleanObject flag) {
lock = o;
this.flagObj = flag;
}
public void run() {
for (int i=1;i<100;i+=2) {
synchronized(lock) {
if (flagObj.flag == true) {
flagObj.flag = false;
lock.notify();
}
else {
try {
while(flagObj.flag == false) {
lock.wait();
}
}
catch (InterruptedException e) {
}
}
System.out.println(i);
}
}
}
}
public class EvenOddThreads {
public static void main(String[] args) {
Object obj = new Object();
BooleanObject flagObj = new BooleanObject(true);
EvenThread et = new EvenThread(obj,flagObj);
OddThread ot = new OddThread(obj,flagObj);
et.setName("even thread");
ot.setName("odd thread");
et.start();
ot.start();
}
}
The problem is with auto-boxing. When you change flag from true to false or vice versa, you are actually getting an entirely new Boolean object. That is, this line:
flag = false;
Is equivalent to:
flag = new Boolean(false);
Once that happens your two threads are then referring to two different Boolean objects, so their flags end up un-synchronized and neither thread is able to signal the other to wake up. When OddThread changes the flag EvenThread still has the old flag object so it doesn't see the new value.
Because a Boolean object is immutable you'll need to change your flag to use some other mutable object which can change values in place without creating new objects. That, or have both classes refer to a common (perhaps global) variable.
As #erickson suggests you could use AtomicBoolean which is mutable. Another kludgy way to do it would be to change flag to:
boolean[] flag = new boolean[1];
And then use flag[0] every where. Both threads would then be able to change flag[0] while always referencing the same boolean[] array object. You wouldn't have the auto-boxing problem.
...
Also, it is a good idea to wrap any call to wait() in a loop. A wait() can be subject to spurious wakeups where the call returns even though nobody has actually called notify(). To workaround that you should always check your guarding condition after waking up to make sure the wakeup isn't spurious.
while (flag == true) {
lock.wait();
}
Update
I have made the changes based on your suggestions above; but i am not getting the expected output. I will paste the modified code above. Here is the output i am getting 1 2 4 3 5 6 8 7 9 10 11 13 12 15 17 14....
When you end up waiting, once you are woken up you don't toggle flag and notify the other thread. I advise reorganizing your code a bit so it looks like "wait; print; notify". Something like:
synchronized (lock) {
while (flagObj.flag == false) {
lock.wait();
}
System.out.println(i);
flagObj.flag = false;
lock.notify();
}
The problem isn't autoboxing. The same thing would happen even if boolean primitives were used throughout.
It's a scope problem. Each thread instance has its own flag member, and they are completely distinct. When you assign a new value in one thread, the other thread cannot see it.
To make this work as intended, make a mutable boolean wrapper (an AtomicBoolean would do the job, although you wouldn't be making use of its concurrency properties in this application), and pass that wrapper to each thread. Each thread would mutate that single object, rather than assigning a new object to its own variable.
You actually have two problems here.
1) The first one is this
if (flag == true) {
flag = false;
lock.notify();
}
You pass the flag reference to the constructor, but then you change each thread's local flag, which won't affect the other thread's value.
Try something like
class Monitor
{
public static volatile boolean flag;
}
And then use Monitor.flag in each thread.
2) The second problem (once the 1st one is fixed), is that each thread needs to have this
synchronized(lock)
{
lock.notify();
}
at the end after the loop because otherwise one thread will wait() but the other thread is already done.

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