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.
Related
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'm trying to solve the sleeping barber problem in java i'm having a problem when trying to make a thread leave the monitor when a signle condition is met here's the code:
public void getHairCut(String threadName) {
enter();
if(!barberSleeping) {
if(freeSeats == 0) {
System.out.println(threadName + " waiting...");
freeSeats--;;
hairCut.await();
}
else {
System.out.println("waiting room is full " + threadName + " is leaving...");
return; // i'm having a problem here,i want the thread to return from the method and release the monitor's lock to let other threads enter
}
}
// some code
leave();
}
thanks in advance.
Can't you wrap the critical section in a try-finally block?
public void getHairCut(String threadName) {
enter();
try {
if(!barberSleeping) {
if(freeSeats == 0) {
System.out.println(threadName + " waiting...");
freeSeats--;;
hairCut.await();
}
else {
System.out.println("waiting room is full " + threadName + " is leaving...");
return; // i'm having a problem here,i want the thread to return from the method and release the monitor's lock to let other threads enter
}
}
// some code
}
finally {
leave(); // this would be called in any case
}
}
The finally block will be executed in any case:
when execution reaches the bottom
when an exception is thrown
when the code block is quit because of a return statement
In very brief the situation is as follows:
In order to be capable of waiting for a condition to be met a thread (say T0) must first acquire a lock for itself. After that it might (or might not) be suspended because some condition is not yet met by calling a wait-function. If this condition will be met at a later point (by another thread e.g. T1, because T0 is suspended), T1 might signal the suspended Thread T0 to reclaim its work. In order to signal the condition which was responsible for suspending T0, T1 also needs to acquire the one lock associated with the condition.
A corresponding code would look like:
// relevant prior assumptions
Lock myLock = new ReentrantLock();
Condition myCondition = myLock.newCondition();
// code that might suspend thread T0
try {
myLock.lock();
while (someCondition == false) {
myCondition.await();
}
} finally {
myLock.unlock();
}
// code that signals T0 to wake up and continue with its wrkr where it stopped (which is exactly aone line after the call to myCondition.awayit())
try {
myLock.lock();
myCondition.signal();
} finally {
myLock.unlock();
}
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.
I want to stop a running thread immediately. Here is my code:
Class A :
public class A() {
public void methodA() {
For (int n=0;n<100;n++) {
//Do something recursive
}
//Another for-loop here
//A resursive method here
//Another for-loop here
finishingMethod();
}
}
Class B:
public class B() {
public void runEverything() {
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
A a = new A();
a.methodA();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
My problem is that i need to be able to stop the thread in Class B even before the thread is finished. I've tried interrupt() method, but that doesn't stop my thread. I've also heard about using shared variable as a signal to stop my thread, but I think with long recursive and for-loop in my process, shared-variable will not be effective.
Any idea ?
Thanks in advance.
Thread.interrupt will not stop your thread (unless it is in the sleep, in which case the InterruptedException will be thrown). Interrupting basically sends a message to the thread indicating it has been interrupted but it doesn't cause a thread to stop immediately.
When you have long looping operations, using a flag to check if the thread has been cancelled is a standard approach. Your methodA can be modified to add that flag, so something like:
// this is a new instance variable in `A`
private volatile boolean cancelled = false;
// this is part of your methodA
for (int n=0;n<100;n++) {
if ( cancelled ) {
return; // or handle this however you want
}
}
// each of your other loops should work the same way
Then a cancel method can be added to set that flag
public void cancel() {
cancelled = true;
}
Then if someone calls runEverything on B, B can then just call cancel on A (you will have to extract the A variable so B has a reference to it even after runEverything is called.
I think you should persevere with using Thread.interrupt(). But what you need to do to make it work is to change the methodA code to do something like this:
public void methodA() throws InterruptedException {
for (int n=0; n < 100; n++) {
if (Thread.interrupted) {
throw new InterruptedException();
}
//Do something recursive
}
// and so on.
}
This is equivalent declaring and using your own "kill switch" variable, except that:
many synchronization APIs, and some I/O APIs pay attention to the interrupted state, and
a well-behaved 3rd-party library will pay attention to the interrupted state.
Now it is true that a lot of code out there mishandles InterruptedException; e.g. by squashing it. (The correct way to deal with an InterruptedException is to either to allow it to propagate, or call Thread.interrupt() to set the flag again.) However, the flip side is that that same code would not be aware of your kill switch. So you've got a problem either way.
You can check the status of the run flag as part of the looping or recursion. If there's a kill signal (i.e. run flag is set false), just return (after whatever cleanup you need to do).
There are some other possible approaches:
1) Don't stop it - signal it to stop with the Interrupted flag, set its priority to lowest possible and 'orphan' the thread and any data objects it is working on. If you need the operation that is performed by this thread again, make another one.
2) Null out, corrupt, rename, close or otherwise destroy the data it is working on to force the thread to segfault/AV or except in some other way. The thread can catch the throw and check the Interrupted flag.
No guarantees, sold as seen...
From main thread letsvsay someTask() is called and t1.interrput is being called..
t1.interrupt();
}
private static Runnable someTask(){
return ()->{
while(running){
try {
if(Thread.interrupted()){
throw new InterruptedException( );
}
// System.out.println(i + " the current thread is "+Thread.currentThread().getName());
// Thread.sleep( 2000 );
} catch (Exception e) {
System.out.println(" the thread is interrputed "+Thread.currentThread().getName());
e.printStackTrace();
break;
}
}
o/P:
java.lang.InterruptedException
at com.barcap.test.Threading.interrupt.ThreadT2Interrupt.lambda$someTask$0(ThreadT2Interrupt.java:32)
at java.lang.Thread.run(Thread.java:748)
the thread is interrputed Thread-0
Only t1.interuuption will not be enough .this need check the status of Thread.interrupted() in child thread.
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.