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.
Related
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).
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
}
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!
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.
I'm using a thread that is continuously reading from a queue.
Something like:
public void run() {
Object obj;
while(true) {
synchronized(objectsQueue) {
if(objectesQueue.isEmpty()) {
try {
objectesQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
obj = objectesQueue.poll();
}
}
// Do something with the Object obj
}
}
What is the best way to stop this thread?
I see two options:
1 - Since Thread.stop() is deprecated, I can implement a stopThisThread() method that uses a n atomic check-condition variable.
2 - Send a Death Event object or something like that to the queue. When the thread fetches a death event, it exits.
I prefer the 1st way, however, I don't know when to call the stopThisThread() method, as something might be on it's way to the queue and the stop signal can arrive first (not desirable).
Any suggestions?
The DeathEvent (or as it is often call, "poison pill") approach works well if you need to complete all of the work on the queue before shutting down. The problem is that this could take a long time.
If you want to stop as soon as possible, I suggest you do this
BlockingQueue<O> queue = ...
...
public void run() {
try {
// The following test is necessary to get fast interrupts. If
// it is replaced with 'true', the queue will be drained before
// the interrupt is noticed. (Thanks Tim)
while (!Thread.interrupted()) {
O obj = queue.take();
doSomething(obj);
}
} catch (InterruptedException ex) {
// We are done.
}
}
To stop the thread t that instantiated with that run method, simply call t.interrupt();.
If you compare the code above with other answers, you will notice how using a BlockingQueue and Thread.interrupt() simplifies the solution.
I would also claim that an extra stop flag is unnecessary, and in the big picture, potentially harmful. A well-behaved worker thread should respect an interrupt. An unexpected interrupt simply means that the worker is being run in a context that the original programmer did not anticipate. The best thing is if the worker to does what it is told to do ... i.e. it should stop ... whether or not this fits with the original programmer's conception.
Why not use a scheduler which you simply can stop when required? The standard scheduler supports repeated scheduling which also waits for the worker thread to finish before rescheduling a new run.
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleWithFixedDelay(myThread, 1, 10, TimeUnit.SECONDS);
this sample would run your thread with a delay of 10 sec, that means when one run finishes, it restarts it 10 seconds later. And instead of having to reinvent the wheel you get
service.shutdown()
the while(true) is not necessary anymore.
ScheduledExecutorService Javadoc
In your reader thread have a boolean variable stop. When you wish for this thread to stop set thius to true and interrupt the thread. Within the reader thread when safe (when you don't have an unprocessed object) check the status of the stop variable and return out of the loop if set. as per below.
public class readerThread extends Thread{
private volitile boolean stop = false;
public void stopSoon(){
stop = true;
this.interrupt();
}
public void run() {
Object obj;
while(true) {
if(stop){
return;
}
synchronized(objectsQueue) {
if(objectesQueue.isEmpty()) {
try {
objectesQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
if(stop){
return;
}
obj = objectesQueue.poll();
// Do something with the Object obj
}
}
}
}
public class OtherClass{
ThreadReader reader;
private void start(){
reader = ...;
reader.start();
}
private void stop(){
reader.stopSoon();
reader.join(); // Wait for thread to stop if nessasery.
}
}
Approach 1 is the preferred one.
Simply set a volatile stop field to true and call interrupt() on the running thread. This will force any I/O methods that wait to return with an InterruptedException (and if your library is written correctly this will be handled gracefully).
I think your two cases actually exhibit the same potential behavior. For the second case consider Thread A adds the DeathEvent after which Thread B adds a FooEvent. When your job Thread receives the DeathEvent there is still a FooEvent behind it, which is the same scenario you are describing in Option 1, unless you try to clear the queue before returning, but then you are essentially keeping the thread alive, when what you are trying to do is stop it.
I agree with you that the first option is more desirable. A potential solution would depend on how your queue is populated. If it is a part of your work thread class you could have your stopThisThread() method set a flag that would return an appropriate value (or throw Exception) from the enqueuing call i.e.:
MyThread extends Thread{
boolean running = true;
public void run(){
while(running){
try{
//process queue...
}catch(InterruptedExcpetion e){
...
}
}
}
public void stopThisThread(){
running = false;
interrupt();
}
public boolean enqueue(Object o){
if(!running){
return false;
OR
throw new ThreadNotRunningException();
}
queue.add(o);
return true;
}
}
It would then be the responsibility of the object attempting to enqueue the Event to deal with it appropriately, but at the least it will know that the event is not in the queue, and will not be processed.
I usually put a flag in the class that has the Thread in it and in my Thread code I would do. (NOTE: Instead of while(true) I do while(flag))
Then create a method in the class to set the flag to false;
private volatile bool flag = true;
public void stopThread()
{
flag = false;
}
public void run() {
Object obj;
while(flag) {
synchronized(objectsQueue) {
if(objectesQueue.isEmpty()) {
try {
objectesQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
obj = objectesQueue.poll();
}
}
// Do something with the Object obj
}
}