How to use wait() and notifyAll() to run thread one by one? - java

I write a House class, it has four synchronized method.
I write four threads, and want they run one by one. but just first and second have run, the other havn't ?
public class House {
private boolean hasFoundation = false;
private boolean hasFrame = false;
private boolean hasWall = false;
private boolean hasRoof = false;
public synchronized void buildFoundation() {
hasFoundation = true;
System.out.println("foundation Ok");
notifyAll();
}
public synchronized void buildFrame() throws InterruptedException {
if (!hasFoundation) {
wait();
} else {
hasFrame = true;
System.out.println("frame ok");
notifyAll();
}
}
public synchronized void buildWall() throws InterruptedException {
if (!hasFrame) {
wait();
} else {
hasWall = true;
System.out.println("wall ok");
notifyAll();
}
}
public synchronized void buildRoof() throws InterruptedException {
if (!hasWall) {
wait();
} else {
hasRoof = true;
System.out.println("roof ok");
notifyAll();
}
}
}
public class BuildAHouse {
public static void main(String[] args) {
House house = new House();
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new FoundationTeam(house));
exec.execute(new WallTeam(house));
exec.execute(new RoofTeam(house));
exec.execute(new FrameTeam(house));
exec.shutdown();
}
}
when run the main(),the result just:
foundation ok
frame ok
the other two thread havn't run! why?
the ...Team class like this:
public class FoundationTeam implements Runnable {
private House house;
public FoundationTeam(House house) {
this.house = house;
}
#Override
public void run() {
house.buildFoundation();
}
}
this is just a demo, I want know how to use wait() and notifyAll().
Please just solve this problem ok? Its' just a part of all what i want do.
Please just tell me why it's doesn't work, and how to solve?
when call wait(), this object won't be release? and other threads can't call the other synchronized methods?

If your method does wait(), it isn't going to run anything in the else block
Note: wait() can wake spuriously, a while loop is recommended.

the other two thread havn't run! why?
As #Peter mentioned and you've figured out, you need while(!boolean) loop around your wait loops. This is necessary for a couple of reasons.
As Peter mentions, the wait() might return because of a spurious wakeup instead of a proper notify() call. You need to make sure that the condition you are waiting for has actually been set and then loop and call wait() again if it hasn't.
In your case however, it's less about spurious wakeups and more about how your program is written. Because you have one synchronized object (the House object), when you call notifyAll() all of teams threads are awoken. When the buildFoundation() method is called, it sets hasFoundation to true and wakes up all of the teams. But only the framing team can actually start work -- the other teams need to loop around and wait some more until their boolean has been set to true.
You could change your code to use different locks for each of the steps which would make the code a bit easier to follow although you would still need the while loops.
Lastly, as you've already figured out, your if ... else ... pattern makes no sense because when the teams are waiting, when they are notified, their build method will just return because the other stuff is in the else.

It's work!
public synchronized void buildWall() throws InterruptedException {
while (!hasFrame) {
wait();
}
hasWall = true;
System.out.println("wall ok");
notifyAll();
}
add the "while()", but i alredy don't know why!

Related

Ensure that java thread is really suspended

I have following class:
public class PawnThread implements Runnable {
public void start() {
thread.start();
}
#Override
public void run() {
try {
while (... some finish condition ...) {
move();
synchronized (this) {
while (suspendFlag) {
wait();
}
}
}
} catch (InterruptedException e) {
System.err.println(pawn.toString() + ": thread interrupted :(");
}
}
void move() {
... some blocking actions
}
synchronized void suspend() {
suspendFlag = true;
}
synchronized void resume() {
suspendFlag = false;
notify();
}
}
Now I have a list of its objects:
private final List<PawnThread> pawnThreadList;
I defined some helper method to suspend all of them:
public void suspendAll() {
pawnThreadList.forEach(PawnThread::suspend);
}
Now suspend() method is only about changing flag. The requirement is, that when I leave suspendAll() method, all threads should be actually paused (they cannot be in RUNNABLE state) - for now it is not a case, beacause for some of them, it may take some time to actually finish their job before pause.
I would be grateful for advice what is correct design for this soulution.
Regards
Make PawnThread#suspend() wait for suspension to be completed:
public class PawnThread implements Runnable {
private final Waiter suspender = new Waiter();
private final Waiter suspending = new Waiter();
#Override
public void run() {
try {
while (...) {
suspending.suspend();
move();
suspending.resume();
suspender.await();
}
} catch (InterruptedException e) {
...
}
}
void suspend() throws InterruptedException {
suspender.suspend();
suspending.await();
}
void resume() {
suspender.resume();
}
}
public class Waiter {
private boolean waiting;
public synchronized void await() throws InterruptedException {
while (waiting) {
wait();
}
}
public synchronized void suspend() {
waiting = true;
}
public synchronized void resume() {
waiting = false;
notify();
}
}
The requirement is impossible to satisfy, but also makes no sense. In order for the thread to communicate the fact that it has suspended, the thread must be running. There is no way to ensure the thread has completed the suspension process.
But this is also not a sensible requirement. How can it possibly matter whether the thread has suspended itself or is about to suspend itself, so long as it has nothing left to do but suspend itself?
A sensible requirement should be satisfied by having each thread set some indication somewhere that it has received the suspend request and is about to stop executing. Then the calling thread can wait for all threads to have provided that indication.
Universal correct design for any parallel solution is to define streams of tokens and firing rule (see Petry Net tedminology). Most simple and useful firing rule is to start an action when all input tokens are ready. I your case, input tokens are hidden in whle condition and in suspend condition. Your mistake is you defined suspend condition as negative, while all tokens must be defined as positive. That is, a thread works where there are enough tokens, and stops when they are exhausted, and then thread waits while the number of tokens is increased by external threads.
Tokens may be of 2 kinds - black (pure permissions), passed by Semaphores, and color (messages), passed by BlockingQueues. These 2 communicator classes cover most of use cases. In some complex cases, user can create custom communicators using synchronized/wait/notify.
So canonical way to design any parallel program is as follows:
design Petry Net, with places for tokens (communicators), and transitions (actions).
map places to Semaphores/BlockingQueues/CustomCommunicators, and transition to threads (or Actors).

Interrupting unknown thread

Consider the following (simplified) class, designed to allow my entire component to enter some interim state before completely stopping. (The purpose of the interim state is to allow the component to complete its existing tasks, but reject any new ones).
The component might be started and stopped multiple times from any number of threads.
class StopHandler {
boolean isStarted = false;
synchronized void start() {isStarted = true;}
//synchronized as I do want the client code to block until the component is stopped.
//I might add some async method as well, but let's concentrate on the sync version only.
synchronized void stop(boolean isUrgent) {
if (isStarted) {
if (!isUrgent) {
setGlobalState(PREPARING_TO_STOP); //assume it is implemented
try {Thread.sleep(10_000L);} catch (InterruptedException ignored) {}
}
isStarted = false;
}
}
The problem with the current implementation is that if some client code needs to urgently stop the component while it is in the interim state, it will still have to wait.
For example:
//one thread
stopHandler.stop(false); //not urgent => it is sleeping
//another thread, after 1 millisecond:
stopHandler.stop(true); //it's urgent, "please stop now", but it will wait for 10 seconds
How would you implement it?
I might need to interrupt the sleeping thread, but I don't have the sleeping thread object on which to call 'interrupt()'.
How about storing a reference to current Thread (returned by Thread.currentThread()) in a field of StopHandler directly before you call sleep? That would allow you you to interrupt it in the subsequent urgent call in case the Thread is still alive.
Couldn't find a better solution than the one suggested by Lars.
Just need to encapsulate the sleep management for completeness.
class SleepHandler {
private final ReentrantLock sleepingThreadLock;
private volatile Thread sleepingThread;
SleepHandler() {
sleepingThreadLock = new ReentrantLock();
}
void sleep(long millis) throws InterruptedException {
setSleepingThread(Thread.currentThread());
Thread.sleep(millis);
setSleepingThread(null);
}
void interruptIfSleeping() {
doWithinSleepingThreadLock(() -> {
if (sleepingThread != null) {
sleepingThread.interrupt();
}
});
}
private void setSleepingThread(#Nullable Thread sleepingThread) {
doWithinSleepingThreadLock(() -> this.sleepingThread = sleepingThread);
}
private void doWithinSleepingThreadLock(Runnable runnable) {
sleepingThreadLock.lock();
try {
runnable.run();
} finally {
sleepingThreadLock.unlock();
}
}
}
With this helper class, handling of the original problem is trivial:
void stop(boolean isUrgent) throws InterruptedException {
if (isUrgent) {sleepHandler.interruptIfSleeping();} //harmless if not sleeping
try {
doStop(isUrgent); //all the stuff in the original 'stop(...)' method
} catch (InteruptedException ignored) {
} finally {
Thread.interrupted(); //just in case, clearing the 'interrupt' flag as no need to propagate it futher
}

How to await a Condition without the chance of await being called after signal in Java?

I have a wait/notify mechanism in my code which basically wraps Lock and Condition like this:
class ConditionWithTimeout { // timeout part omitted
private Lock lock = new ReentrantLock();
private Condition cond = lock.newCondition();
public void doWait() throws InterruptedException {
lock.lock();
cond.await();
lock.unlock();
}
public void doNotify() {
lock.lock();
cond.signalAll();
lock.unlock();
}
}
My problem is that if I do something like this:
someFunction();
myCond.doWait();
it is possible that if someFunction calls doNotify at some point on myCondition I will wait until myCondition times out because doWait in someFunction might be executed before this code jumps to the next line to execute myCond.doWait.
I worked around it by adding a preWaitFn:
class ConditionWithTimeout {
private Lock lock = new ReentrantLock();
private Condition cond = lock.newCondition();
private Executor hookExecutor = Executors.newSingleThreadExecutor();
public void doWait() throws InterruptedException {
doWait(() -> {
});
}
public void doWait(Runnable preWaitFn) throws InterruptedException {
lock.lock();
hookExecutor.execute(preWaitFn);
cond.await();
lock.unlock();
}
public void doNotify() {
lock.lock();
cond.signalAll();
lock.unlock();
}
}
and it works now but this seems like a code smell to me because it is still possible that doNotify is called before cond.await is called.
So my question is that what is the best practice in such situations? I need to block until someFunction finishes its work but I wish to avoid such corner cases as this.
The usual pattern is to check some logical condition and use the signal as a means of notifying another thread that the condition has been updated. In your case, a simple flag should suffice:
private boolean flag = false;
public void doWait() throws InterruptedException {
lock.lock();
try {
// Loop is necessary to avoid spurious wakeup
while (!flag) {
cond.await();
}
} finally {
// Unlock in finally in case exception is thrown
lock.unlock();
}
}
public void doNotify() {
lock.lock();
try {
flag = true;
cond.signalAll();
} finally {
lock.unlock();
}
}
You could try using a CountDownLatch. Depending on your use case, this may not be the best answer - it works if you can create a new instance of your flag object for each call, but not if you need to reuse one. The linked Javadoc page contains examples of how to use it. This is basically a off-the-shelf replacement for shmosel's answer.

how to destroy a thread , pause/suspend a thread , resume/runAgain a thread?

Hey guys
I am using runnable outside the oncreate in my android application where i have used thread to setprogress of ProgressBar. What i dont know is how to stop/destry the thread when stop button is pressed since thread.stop is not a method and how to resume from that , how to even destroy the thread.
I know i have to make some methods and members in runnable but i dont exactly know what??
Thread.stop() is no longer used since it was considered dangerous: http://download.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html.
You must let the thread come naturally to an end as a result of a variable change. The link also gives some advice about how to achieve this.
public class MyThread extends Thread {
private boolean threadDone = false;
public void done() {
threadDone = true;
}
public void run() {
while (!threadDone) {
// work here
// modify common data
}
}
}
Warning: make sure you either use a guarded block in the looping code, a method that blocks itself, or a Thread.sleep(..). Thread.sleep is the most primitive of these if you don't understand guarded blocks, but it will work. You could also wait forever and use the interrupt mechanism to cancel the thread which is thrown as InterruptedException in the try-catch block when you use a wait or sleep. For this, use !Thread.currentThread().isInterrupted() as the loop guard condition, then use your Thread object and call thread.interrupt().
To control a Java thread, you should add methods to the object that can be called by other objects which set variables read by your run() method. You don't give much information on exactly what you're doing, but here's a possible pattern:
public class ProgressBarUpdater implements Runnable{
private volatile boolean paused = false;
private volatile boolean finished = false;
/* other fields, constructor etc. */
public void run(){
while(!finished){
updateProgressBar();
while(paused && !finished){
try{
Thread.sleep(1000); //Busy wait - should really use wait/notify, but that's another lesson
}
catch(InterruptedException e){
}
}
}
}
public synchronized void pauseProgressBar(){
paused = true;
}
public synchronized void unPauseProgressBar(){
paused = false;
//call notify() here when you switch to wait/notify.
}
public void stopProgressBar(){
finished = true;
//call notify() here too.
}
}
You will probably want to use more robust synchronisation around the control variables, and, as mentioned in the comments, wait/notify rather than a busy wait.
Use as so:
ProgressBarUpdater pbu = new ProgressBarUpdater();
Thread t = new Thread(pbu);
t.start();
Thread.sleep(10000); //let the progress bar run for ten seconds.
pbu.pauseProgressBar();
Thread.sleep(10000); //pause it for ten seconds.
pbu.unPauseProgressBar();
Thread.sleep(10000); //restart for another ten seconds.
pbu.stopProgressBar(); //stop progress bar.
You have a few options and they depend on how you define the various states of your thread.
A thread is effectively stoped when it exits the run() method.
To "pause" and "resume" a thread's execution you can can use wait() and notify().
To illustrate this, here's a quick example:
class MyThread implements Runnable {
private boolean keepRunning = false;
private boolean isPaused = false;
public void run() {
keepRunning = true;
try {
while (keepRunning) {
// do stuff here
if (isPaused) {
synchronized (this) {
// wait for resume() to be called
wait();
isPaused = false;
}
}
}
} catch (Exception ex) {
// do stuff
}
}
// note that as-is this won't do anything to a paused thread until
// it is resumed.
public void stop() {
keepRunning = false;
}
public void pause() {
isPaused = true;
}
public synchronized void resume() {
// notify anybody waiting on "this"
notify();
}
}
Have the other thread check a boolean flag (isCancelled, or something like that) periodically. Initially is is false.
From your stop button code, set this value to true.
When your thread next checks the flag and finds it to be true, the thread should kill itself.

Java, wait and notifyAll: guard against spurious wakeups

I have several threads that does some work, and then must go to sleep/wait for an undetermined time. Later they all need to be waken up and resume their work. I can do this by calling wait() on an object and then notifyall() on the same object when they need to resume. When researching this issue i discovered this tutorial: http://tutorials.jenkov.com/java-concurrency/thread-signaling.html
Apparantly it is good practice to guard against missed signals and spurious wakeups by storing the signal inside the signal class and check the signal member variable inside a while loop.
Here is the code example from the tutorial:
public class MonitorObject{
}
public class MyWaitNotify3{
MonitorObject myMonitorObject = new MonitorObject();
boolean wasSignalled = false;
public void doWait(){
synchronized(myMonitorObject){
while(!wasSignalled){
try{
myMonitorObject.wait();
} catch(InterruptedException e){...}
}
//clear signal and continue running.
wasSignalled = false;
}
}
public void doNotify(){
synchronized(myMonitorObject){
wasSignalled = true;
myMonitorObject.notify();
}
}
}
This code is working, but I need to wake up all threads and not just one. If I replace myMonitorObject.notify(); with myMonitorObject.notifyAll(); that will not work because the first thread that resumes work will set the wasSignalled flag to false and all the other threads will be trapped in the while loop.
I have made some changes that will enable me to wake up all threads:
MonitorObject myMonitorObject = new MonitorObject();
boolean wasSignalled = false;
public void doWait(){
synchronized(myMonitorObject){
while(!wasSignalled){
try{
myMonitorObject.wait();
} catch(InterruptedException e){
}
}
}
}
public void resetSignal() {
wasSignalled = false;
}
public void doNotifyAll() {
synchronized(myMonitorObject){
wasSignalled = true;
myMonitorObject.notifyAll();
}
}
But this is not a very good solution, because now I can't wake up just one thread, and I have to reset the signal after doNotify before I can use doWait again.
Does anyone have a solution that will enable me to use both notify or notifyAll on the threads that is waiting?
And one thing about the example I do not understand, why do I have to use a separate MonitorObject class at all? Why can't I just call wait and notify on the MyWaitNotify class itself?
Like this:
public class WaitNotify {
boolean wasSignalled = false;
public void doWait(){
synchronized(this){
while(!wasSignalled){
try{
wait();
} catch(InterruptedException e){
}
}
}
}
public void resetSignal() {
wasSignalled = false;
}
public void doNotifyAll() {
synchronized(this){
wasSignalled = true;
notifyAll();
}
}
}
This seems to be working, any reason I should not be doing this?
Use a generation integer. When a thread blocks, block until the generation integer changes. Before calling notifyAll, increment the generation integer.
Phaser is a good high-level tool for this kind of use case.
final Phaser phaser = new Phaser(1);
doNotify()
phaser.arrive(); // increase phase
doWait()
int phase = phaser.getPhase();
phaser.awaitAdvance( phase ); // await phase change
synchronized on a privately owned object has the advantage that nobody else could do synchronized on it. If you do synchronized(this), there is a chance that someone else may also want to use this as a lock object.

Categories

Resources