Pausing/sleeping threads in java [duplicate] - java

I state that I read about thread, but I've never used.
So I ask to you :)
I have two thread: A and B,
where A manages the GUI, and B manages the logic.
I would start with A.
Then when A draw the GUI, I would pause it, to wait B that reach a point X into run method.
And when B reach the X point into run method, I pause B, and resume A.
A and B share some variable to manage the GUI, and the logic...
Can I do it? if yes, how? :)

Using wait() and notify() methods:
wait() - Causes the current thread to wait until another thread invokes the
notify() method or the notifyAll() method for this object.
notify() - Wakes up a single thread that is waiting on this object's monitor.

You can block threads using the wait and notify methods of the Object class, but it can be tricky to get right. Here's an example inside an infinite loop in a Runnable:
public class Example implements Runnable {
private volatile boolean running = true;
private volatile boolean paused = false;
private final Object pauseLock = new Object();
#Override
public void run() {
while (running) {
synchronized (pauseLock) {
if (!running) { // may have changed while waiting to
// synchronize on pauseLock
break;
}
if (paused) {
try {
pauseLock.wait(); // will cause this Thread to block until
// another thread calls pauseLock.notifyAll()
// Note that calling wait() will
// relinquish the synchronized lock that this
// thread holds on pauseLock so another thread
// can acquire the lock to call notifyAll()
// (link with explanation below this code)
} catch (InterruptedException ex) {
break;
}
if (!running) { // running might have changed since we paused
break;
}
}
}
// Your code here
}
}
public void stop() {
running = false;
// you might also want to interrupt() the Thread that is
// running this Runnable, too, or perhaps call:
resume();
// to unblock
}
public void pause() {
// you may want to throw an IllegalStateException if !running
paused = true;
}
public void resume() {
synchronized (pauseLock) {
paused = false;
pauseLock.notifyAll(); // Unblocks thread
}
}
};
(For more information on why we need to synchronize as illustrated above whilst calling wait and notifyAll, see the Java tutorial on the subject.)
If another Thread calls this Runnable's pause() method, then the Thread running the runnable will block when it gets to the top of the while loop.
Note that it is not possible to pause a thread at any arbitrary point. You need the Thread to periodically check whether it should pause and block itself if so.

I would expect that you don't need to pause the GUI thread. The operating system will take care of that, and it needs to be ready to respond in case the user does something.
One other thought is to make sure the shared variables are properly synchronized between the two threads. I tried answering a question relating to that recently, see here.

you can use a CountDownLatch. When Thread A has to wait for Thread B will call countDownLatchInstance.await(); When B reach the X point will invoke countDownLatchInstance.countDown(); allowing A to continue its execution flow.
When you say
A manages the GUI
I hope you do not refer to the UI/Main Thread
,

public class Mutex {
private final AtomicBoolean lock;
private final Object mutex;
public Mutex(boolean lock) {
this.lock = new AtomicBoolean(lock);
this.mutex = new Object();
}
public void step() {
if (lock.get()) synchronized(mutex) {
try {
mutex.wait();
} catch (InterruptedException ex) {}
}
}
public void lock() {
lock.set(true);
}
public void unlock() {
lock.set(false);
synchronized(mutex) {
mutex.notify();
}
}
}
Just add Mutex object to your thread and make getter.
public class MyThread extends Thread {
private final Mutex mutex;
public MyThread() {
this.mutex = new Mutex(false);
}
public Mutex getMutex() {
return this.mutex;
}
#Override
public void run() {
while (!isInterrupted()) {
mutex.step();
// do your code
}
}
}
If you want to pause the thread just call
myThread.getMutex().lock();
If you want to resume the thread just call
myThread.getMutex().unlock();

That's the way I got thread's wait and notify working for me:
public class Main {
public static void main(String[] args) {
final Object lock = new Object();
MyThread t = new MyThread();
t.lock = lock;
t.run();
while (true) {
try {
synchronized (lock) {
lock.wait();
}
System.out.println("hello");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class MyThread extends Thread {
Object lock;
#Override
public void run() {
JFrame fr = new JFrame("Anothing");
JButton btn = new JButton("Next");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
synchronized (lock) {
lock.notify();
}
}
});
fr.setLayout(new FlowLayout());
fr.add(btn);
fr.setSize(400, 400);
fr.setVisible(true);
}
}
Then, whenever I press the button, the other thread wakes up, executes one round and waits for a new clicking.

The java primitive to suspend and resume a thread is deprecated. See this to figure how you can achieve best what you need - http://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
Check how you can do the equivalent of suspend & resume
What should I use instead of Thread.suspend and Thread.resume?
As with Thread.stop, the prudent approach is to have the "target thread" poll a variable indicating the desired state of the thread (active or suspended). When the desired state is suspended, the thread waits using Object.wait. When the thread is resumed, the target thread is notified using Object.notify.
Example code is given in the same answer to help you achieve this.

Related

Thread synchronization with Locks and Conditions

I have a problem to understand Locks and Conditions in Java, i do not understand why my code ends up in a deadlock. My programm consists of a Mainthread and a Subthread, subthread is a member of Mainthread. Both threads run in an infinite loop, Subthread's loop is supposed to execute exactly one iteration as soon as it receives the signal for startCond from the Mainthread. Mainthread should wait for the finishCond signal to continue.
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
public static void main(String[] args) {
LockTest lt = new LockTest();
Mainthread m1 = lt.new Mainthread();
m1.start();
}
public class Mainthread extends Thread {
private Subthread sub = new Subthread();
public void run(){
System.out.println("Main start");
sub.start();
while(!isInterrupted()) {
try {
sub.getStartLock().lock();
sub.getStartCond().signal();
sub.getStartLock().unlock();
sub.getFinishLock().lock();
sub.getFinishCond().await();
sub.getFinishLock().unlock();
System.out.println("Main done");
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Subthread extends Thread {
private Lock startLock = new ReentrantLock();
private Lock finishLock = new ReentrantLock();
private Condition startCond = startLock.newCondition();
private Condition finishCond = finishLock.newCondition();
public Lock getStartLock() {
return startLock;
}
public Lock getFinishLock() {
return finishLock;
}
public Condition getStartCond() {
return startCond;
}
public Condition getFinishCond() {
return finishCond;
}
public void run() {
System.out.println("Sub start");
while(!isInterrupted()) {
try {
startLock.lock();
startCond.await();
startLock.unlock();
finishLock.lock();
finishCond.signal();
finishLock.unlock();
System.out.println("Sub done");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
My expected output would be:
Main done Sub done
(repeated as many times as it was executed in the loops).
Is there a way to solve this problem easier?
The main thread starts, it creates new sub thread and starts it but calling start on a thread does not mean that the thread would receive the processor imeddiatly and that its code will be actually executed.
Main, callss sub.getStartCond().signal(); but at this moment the sub thread is still not running so it misses this signal.
Main, awaits on the finishCond.
Sub starts executing its run method, it goes to the start condition and waits on it for ever.
The deadlock.
Signal wakes up only CURRENTLY waiting thread, it does not 'remember' previous calls.
Use Semaphore instead http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html
it has the semantic of 'counting the permits'.
There might be a more reliable way to do this. I would recommend using a CountDownLatch initialized with a count of 1, instead of a condition. Both the main and child threads can share the same instance of the latch (since the main owns the child that should be easy). The child will call await() and the main will call countDown() when you need to send the signal to the child. I recommend you make the latch private and final.
class ChildThread extends Thread {
private final CountDownLatch signal;
public ChildThread(CountDownLatch signal) {
this.signal = signal;
}
public void run() {
// The loop is necessary in case we get interrupted.
while (true) {
try {
signal.await();
break;
} catch(InterruptedException ignored) {
}
}
// do the work...
}
}
class MainThread extends Thread {
private final ChildThread child;
private final CountDownLatch signalToChild;
public MainThread() {
signalToChild = new CountDownLatch(1);
child = new ChildThread(signalToChild);
}
public void run() {
// I can start the child right away but I'd rather make sure it
// starts if the main thread has started.
child.start();
// prework
// let's signal the child
signalToChild.countDown();
// now the child is working, let's go on with the main thread work
}
}
This works because main and child thread actually share state, i.e., the latch. It does not matter if the main thread decrements the latch before the child thread is actually started, because the child will check this shared state to know if it can start.

How pause and then resume a thread?

I state that I read about thread, but I've never used.
So I ask to you :)
I have two thread: A and B,
where A manages the GUI, and B manages the logic.
I would start with A.
Then when A draw the GUI, I would pause it, to wait B that reach a point X into run method.
And when B reach the X point into run method, I pause B, and resume A.
A and B share some variable to manage the GUI, and the logic...
Can I do it? if yes, how? :)
Using wait() and notify() methods:
wait() - Causes the current thread to wait until another thread invokes the
notify() method or the notifyAll() method for this object.
notify() - Wakes up a single thread that is waiting on this object's monitor.
You can block threads using the wait and notify methods of the Object class, but it can be tricky to get right. Here's an example inside an infinite loop in a Runnable:
public class Example implements Runnable {
private volatile boolean running = true;
private volatile boolean paused = false;
private final Object pauseLock = new Object();
#Override
public void run() {
while (running) {
synchronized (pauseLock) {
if (!running) { // may have changed while waiting to
// synchronize on pauseLock
break;
}
if (paused) {
try {
pauseLock.wait(); // will cause this Thread to block until
// another thread calls pauseLock.notifyAll()
// Note that calling wait() will
// relinquish the synchronized lock that this
// thread holds on pauseLock so another thread
// can acquire the lock to call notifyAll()
// (link with explanation below this code)
} catch (InterruptedException ex) {
break;
}
if (!running) { // running might have changed since we paused
break;
}
}
}
// Your code here
}
}
public void stop() {
running = false;
// you might also want to interrupt() the Thread that is
// running this Runnable, too, or perhaps call:
resume();
// to unblock
}
public void pause() {
// you may want to throw an IllegalStateException if !running
paused = true;
}
public void resume() {
synchronized (pauseLock) {
paused = false;
pauseLock.notifyAll(); // Unblocks thread
}
}
};
(For more information on why we need to synchronize as illustrated above whilst calling wait and notifyAll, see the Java tutorial on the subject.)
If another Thread calls this Runnable's pause() method, then the Thread running the runnable will block when it gets to the top of the while loop.
Note that it is not possible to pause a thread at any arbitrary point. You need the Thread to periodically check whether it should pause and block itself if so.
I would expect that you don't need to pause the GUI thread. The operating system will take care of that, and it needs to be ready to respond in case the user does something.
One other thought is to make sure the shared variables are properly synchronized between the two threads. I tried answering a question relating to that recently, see here.
you can use a CountDownLatch. When Thread A has to wait for Thread B will call countDownLatchInstance.await(); When B reach the X point will invoke countDownLatchInstance.countDown(); allowing A to continue its execution flow.
When you say
A manages the GUI
I hope you do not refer to the UI/Main Thread
,
public class Mutex {
private final AtomicBoolean lock;
private final Object mutex;
public Mutex(boolean lock) {
this.lock = new AtomicBoolean(lock);
this.mutex = new Object();
}
public void step() {
if (lock.get()) synchronized(mutex) {
try {
mutex.wait();
} catch (InterruptedException ex) {}
}
}
public void lock() {
lock.set(true);
}
public void unlock() {
lock.set(false);
synchronized(mutex) {
mutex.notify();
}
}
}
Just add Mutex object to your thread and make getter.
public class MyThread extends Thread {
private final Mutex mutex;
public MyThread() {
this.mutex = new Mutex(false);
}
public Mutex getMutex() {
return this.mutex;
}
#Override
public void run() {
while (!isInterrupted()) {
mutex.step();
// do your code
}
}
}
If you want to pause the thread just call
myThread.getMutex().lock();
If you want to resume the thread just call
myThread.getMutex().unlock();
That's the way I got thread's wait and notify working for me:
public class Main {
public static void main(String[] args) {
final Object lock = new Object();
MyThread t = new MyThread();
t.lock = lock;
t.run();
while (true) {
try {
synchronized (lock) {
lock.wait();
}
System.out.println("hello");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class MyThread extends Thread {
Object lock;
#Override
public void run() {
JFrame fr = new JFrame("Anothing");
JButton btn = new JButton("Next");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
synchronized (lock) {
lock.notify();
}
}
});
fr.setLayout(new FlowLayout());
fr.add(btn);
fr.setSize(400, 400);
fr.setVisible(true);
}
}
Then, whenever I press the button, the other thread wakes up, executes one round and waits for a new clicking.
The java primitive to suspend and resume a thread is deprecated. See this to figure how you can achieve best what you need - http://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
Check how you can do the equivalent of suspend & resume
What should I use instead of Thread.suspend and Thread.resume?
As with Thread.stop, the prudent approach is to have the "target thread" poll a variable indicating the desired state of the thread (active or suspended). When the desired state is suspended, the thread waits using Object.wait. When the thread is resumed, the target thread is notified using Object.notify.
Example code is given in the same answer to help you achieve this.

Java thread causes deadlock

I' m trying to implement some basic start, stop, pause and resume functionality that allows me the following state transitions:
stopped to running
running to stopped
running to paused
paused to running
paused to stopped (causes deadlock)
Most of this works as expected, but the last state transition is not possible, because it makes the thread freeze. Could someone please explain me why that is happening and how to prevent it? Here are the relevant parts of the code:
public class ThreadTest implements Runnable {
private volatile boolean running = false;
private volatile boolean paused = false;
private Thread thread;
public ThreadTest() {
thread = new Thread(this);
}
public void run() {
while (running) {
try {
if (paused) {
synchronized (this) {
while (paused)
wait();
}
}
}
catch (InterruptedException e) {
}
}
}
public synchronized void start() {
if(running && !thread.isAlive())
return;
running = true;
thread = new Thread(this);
thread.start();
}
public synchronized void stop() {
if(!running && thread.isAlive())
return;
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.exit(0);
}
public synchronized void resume() {
if(paused) {
paused = false;
notify();
}
else {
return;
}
}
public synchronized void pause() {
if(!paused) {
paused = true;
}
else {
return;
}
}
}
wait(); in run method will wait forever becuase these is not notify();
When call stop, the thread is running becuase wait for ever, so thread.join() will lock.
You need call notify in stop or change wait for ever to wait(1000);
Let us see what exactly is happening here:
Let us name the threads involved here as T2 (the Thread that you explicitly instantiated and started in your code) and T1 (which invokes the start, stop methods on the T2 thread Object). T1 is probably your main thread, depending on your other unshown code.
You are getting a Deadlock because of the following sequence of events:
(Note1: This is just one possible sequence, there may be other possible sequences in this code which could also cause a deadlock)
Say we do a start(), pause() and then a stop() on the ThreadTest object as follows (say in main()):
ThreadTest t = new ThreadTest();
t.start();
t.pause();
t.stop();
After the pause() executes in T1, T2 acquired a lock on the ThreadTest object by entering the "synchronized(this)" block inside the "if(paused)" condition. (Note2: The "this" here refers NOT to the T2 thread object, but it refers to the ThreadTest object as run() is a method on the ThreadTest class.)
T2 enters into a wait() and releases the ThreadTest object lock (implicitly) just when it enters that wait() call.
When T1 enters stop(), it acquires a lock on the ThreadTest object as stop() is a synchronized method. Inside stop(), T1 calls t2.join(), and waits for T2 to complete.
But T2 is already in a wait() and has no one to wake it up !
Hence the Deadlock !
Note3: Even if we wake T2 up by specifying a timeout in the wait() call or by calling notify() (as suggested by others), it still cannot come out of the wait because it cannot re-acquire (implicitly) the lock (on ThreadTest object), as that is already held by T1 waiting in the join() !
One possible solution:
While there could be many possible solutions, can you try this one ?
In the stop() method, instead of
thread.join();
can you use:
if (!paused) {
thread.join();
} else {
thread.interrupt();
}
In the stop method, call thread.notify(); just after running = false;. (This will notify the waiting thread).
Then you must set paused = false; just before your notify call.
Remove the if (paused) block from your run method.
Change your while (paused) loop to while (paused && running). Alternatively, you could use while (paused) { wait(); if (!running) break;} depending on what control flow you want.
For good measure, add the volatile keyword to the paused and running variable declarations (to create memory fences across threads).

Returning/Stopping the execution of a function on a keypress in Java

I have a certain function in my program that I want to stop on the press of a key. I have a native keyboard hook set up for that purpose. Right now, I call System.exit(0) when that key is detected. However, I don't want to exit the program, just stop that operation and return to where it was called. An example is given below.
public class Main {
public static void main(String[] args) {
System.out.println("Calling function that can be stopped with CTRL+C");
foo(); // Should return when CTRL+C is pressed
System.out.println("Function has returned");
}
}
I've tried putting the call to foo() in a thread so I could call Thread.interrupt() but I want the function call to be blocking, not non-blocking. Also there are blocking IO calls in foo() so I'd rather not deal with interrupts unless it's necessary, because I'd have to deal with ClosedByInterruptException exceptions and that has caused problems before.
Also the body of foo() is very long and has many function calls inside it, so writing if (stop == true) return; in the function is not an option.
Is there a better way to do this than making a blocking thread? If so, how? If not, how would I make a blocking thread?
How about this?
// Create and start the thread
MyThread thread = new MyThread();
thread.start();
while (true) {
// Do work
// Pause the thread
synchronized (thread) {
thread.pleaseWait = true;
}
// Do work
// Resume the thread
synchronized (thread) {
thread.pleaseWait = false;
thread.notify();
}
// Do work
}
class MyThread extends Thread {
boolean pleaseWait = false;
// This method is called when the thread runs
public void run() {
while (true) {
// Do work
// Check if should wait
synchronized (this) {
while (pleaseWait) {
try {
wait();
} catch (Exception e) {
}
}
}
// Do work
}
}
}
(taken from http://www.exampledepot.com/egs/java.lang/PauseThread.html not my own work)

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.

Categories

Resources