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.
Related
I have 4 threads each one is executing different method, I'm able to pull the desire output however the threads are not getting terminated or not able to get out of the loop when the job has finished.
Could someone help me with your opinion.
I think each thread has stuck on await statement and expecting someone to signal it. I tried explicitly signalling all threads after task has been done but no luck.
When one thread signals other doesn't the executing threads recheck the condition of a while loop, since I'm setting the flag to false but it doesn't have any effect.
private int n;
Lock lock = new ReentrantLock();
Condition executeFizz;
Condition executeBuzz;
Condition executeFizzBuzz;
Condition executeNumber;
volatile private boolean flag;
public FizzyBuzz(int n) {
this.n = n;
this.executeFizz = lock.newCondition();
this.executeBuzz = lock.newCondition();
this.executeFizzBuzz = lock.newCondition();
this.executeNumber = lock.newCondition();
this.flag = true;
}
public void fizz() {
lock.lock();
while(true) {
try {
executeFizz.await();
if(!flag) break;
} catch (InterruptedException e) {
}
System.out.println("fizz");
executeNumber.signal();
}
}
public void buzz() {
lock.lock();
while(true) {
try {
executeBuzz.await();
if(!flag) break;
} catch (InterruptedException e) {
}
System.out.println("buzz");
executeNumber.signal();
}
}
public void fizzbuzz() {
lock.lock();
while(true) {
try {
executeFizzBuzz.await();
if(!flag) break;
} catch (InterruptedException e) {
}
System.out.println("fizzbuzz");
executeNumber.signal();
}
}
public void number() throws InterruptedException {
lock.lock();
for(int i=1;i<=n;i++)
{
if(i%3==0&&i%5==0)
{
executeFizzBuzz.signal();
executeNumber.await();
}
else if(i%3==0)
{
executeFizz.signal();
executeNumber.await();
}
else if(i%5==0)
{
executeBuzz.signal();
executeNumber.await();
}
else
{
System.out.println(i);
}
}
flag = false;
executeFizzBuzz.signal();
executeFizz.signal();
executeBuzz.signal();
Maybe this doesn't do what you were thinking it does:
while (flag) {
...
}
That loop will not terminate whenever flag becomes false. It terminates when it tests flag and finds it to be false. That only happens once each time around the loop. You could write the loop like this instead, and it would behave in exactly the same way:
while (true) {
if (! flag) break;
...
}
So if you have this,
while (flag) {
...executeFizz.await()...
}
And if the flag changes from true to false while the thread is stuck in the await() call, then the loop won't terminate until after the await() call returns...
...that will never happen in your example because after the for loop has counted up to n, it sets flag=false; but it does not signal any of the other waiting threads.
#SolomonSlow i tried signalling all 3, but no luck
after adding if condition, at the end of the code I included this code...
My guess is, it's because there is no call to lock.unlock() anywhere in your program. Here's what probably happens:
Three "worker" threads are all in calls to executeXxxxx.await() (each awaiting its own condition variable.)
The "main" thread reaches the end of the loop (It currently is the owner of the lock,) and it signals each of the executeXxxxxx condition variables.
The "main" thread ends, but the lock still is locked. All three of the "worker" threads now have been released from awaiting their respective conditions, but their await() calls can not return until the lock becomes available.
The lock never will become available because there's no running thread that can unlock it.
You need to have every thread call lock.unlock() before it ends.
Can anyone explain this program on inter-thread communication?
// A correct implementation of a producer and consumer.
class Q {
int n;
boolean valueSet = false;
synchronized int get() {
while(!valueSet)
try {
wait();
} catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
System.out.println("Got: " + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n) {
while(valueSet)
try {
wait();
} catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.n = n;
valueSet = true;
System.out.println("Put: " + n);
notify();
}
}
class Producer implements Runnable {
Q q;
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}
}
}
class Consumer implements Runnable {
Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
public void run() {
while(true) {
q.get();
}
}
}
class PCFixed {
public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}
}
Output
Put: 1
Got: 1
Put: 2
Got: 2
Put: 3
Got: 3
Put: 4
Got: 4
......
It is very confusing as far as I am concerned, especially the put and get methods where notify() and wait() are used. Please also explain why a boolean value is used.
So there are 2 threads. Qne is setting values on this Q data structure and the other is reading them. Q uses a boolean flag to tell whether a new value is present, the flag gets cleared once an existing value is read.
Q.get uses wait to block until a new value is available to read. Once it's read the new value it sets the flag back to false.
Q.put waits until the other queue has read the new value before setting it to a new value, then lets the other thread know by setting the boolean flag and calling notify.
Remember that wait gives up the lock so the other thread can acquire it.
The boolean flag is needed because a thread may stop waiting without having been notified. Just because a thread woke up doesn't mean it got a notification. Also, even if the thread gets notified, since the thread gave up the lock when it started to wait, the current state of things is unknown (in general there are multithreaded programs where another thread might sneak in and snag something between the time a thread is notified and the time it can regain the lock) so the thread has to re-test the condition again once it has the lock.
Constructs like wait and notify are building blocks for large concurrent programs, so some things may not make as much sense in a small example with only two threads.
See basically its a multithreaded communication with synchronized methods.
simple rquirement here is
1)first allow to write for producer.
2)next allow to read for consumer.
that is controlled using boolean flag valueSet.
in case of producer means put method of Q, logic works this way
if the valueSet is is true means already write is done then ask put method called thread to wait. so it goes to wait until someone calls notify.
ofcourse it wont continue further logic and keeps on waiting for someone to call notify.
coming to reader means get() of Q,
if the valueSet is is false means writter is executing then ask get method called thread to wait. so it goes to wait until someone calls notify.
so once writer completes the execution it calls notify at the end and now reader threads awake and starts reading.
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.
Trying to exercise my understanding of concurrency in Java, here's the problem:
There can be multiple threads running method A and only one thread running method B (lets say when A() has run for 10 times. So on the 10th time, that thread will run method B. When this happens, it must block threads from running A and allow threads that are already running A complete before running the rest of B. Also, the threads in A shouldn't wait on itself.
edit: All threads are started on A first, there is an outside method that checks when to run B.
My attempt so far looks something like this:
volatile Boolean lock = false; //false = threads in method A allowed to run, thread in method B otherwise
volatile Integer countOfA = 0;
void A(){
boolean continue = false;
synchronized(lock){
if(lock == true){ //there is a thread in B, block threads in A
lock.wait();
increaseCountOfA();
//do work
decreaseCountOfA();
if(countOfA == 0){ //this was the last thread that ran with lock
lock = true;
lock.notify(); //only the thread in B should be waiting on this
}
}else{
continue = true;
}
}
if(continue){
increaseCountOfA();
//do work;
decreaseCountOfA();
}
}
void B(){
synchronized(lock){
if(lock == false){
lock.wait();
if(countOfA > 0){
countOfA.wait();
}
//do work;
lock = false;
lock.notifyAll();
}
}
}
void increaseCountOfA(){
synchronized(countOfA){
countOfA++;
}
}
void decreaseCountOfA(){
synchronized(countOfA){
countOfA--;
}
}
When its ran, it hangs. I'm suspecting a deadlock also I don't know how many levels of synchronization is needed for this problem. Can this be done with just one level?
When you do synchronized(lock) you are synchronizing on the object referred to by lock, not on the variable. You probably want an independent lock object whose value you are not changing. Alternately, you might consider using a higher-level concurrency class like Semaphore.
In this case, you have one thread waiting on Boolean.TRUE, and another posting a notify on Boolean.FALSE.
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.