How Pause and Then Resume a Thread

How pause and then resume a thread?

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.

Pause Thread and resume it from where it stopped

There are plenty of ways to manipulate threads.

suspend(): puts a thread in a suspended state and can be resumed using resume()

stop(): stops a thread

resume(): resumes a thread, which was suspended using suspend().

notify(): Wakes up a single thread.

wait(): makes the current thread wait.. (or sleep) until another thread invokes the notify() method for that thread.

notifyAll(): will wake up all sleeping (waiting) threads.

Note

In the latest versions of Java resume( ), suspend( ) and stop( ) has been deprecated

Question from OP

but when I wake it up, it resumes from where? Does it start from the beginning or from where it left?

Imagine a simple for-loop.

Starting thread 1.
Starting thread 2.
Thread 1: 0
Thread 2: 0
Thread 1: 1
Thread 2: 1
Pausing thread 1.
Thread 2: 2
Thread 2: 3
Thread 2: 4
Resuming thread 1.
Thread 1: 2
Thread 2: 5

Pause/Resume a Thread

You need to change your download() method to check for a stop or pause event and then stop or pause the thread. It has to be this way as the JVM does not know what steps need to be done in order to safely pause/stop the thread.

You may end up using wait but not the way you are using it. wait causes the currently running thread to wait until some calls notify on the object you have called wait on.

In the download method you have a loop (read a block, write a block). You should add two checks in the loop.

while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
if(paused) {
// How do you want to handle pausing? See below for options.
}
if(stopped) {
// delete the file and close the streams.
}
}

How you handle pausing is up to you. I can see two options: Save what you have as ".incomplete" and later restart the download using the Range header or continue looping with a pause (Thread.sleep, Object.wait or whatever).
I would go with the first option (Range Header). It is more work but also more robust.

Pause/resume a thread in C#

Here is an example of pausing some threads cooperatively, by using the PauseTokenSource + PauseToken pair from Stephen Cleary's AsyncEx.Coordination package. This example shows also the use of the analogous CancellationTokenSource + CancellationToken pair, that inspired the creation of the aforementioned pausing mechanism.

var pts = new PauseTokenSource() { IsPaused = true };
var cts = new CancellationTokenSource();
int value = 0;

// Create five threads
Thread[] threads = Enumerable.Range(1, 5).Select(i => new Thread(() =>
{
try
{
while (true)
{
cts.Token.ThrowIfCancellationRequested(); // self explanatory
pts.Token.WaitWhilePaused(cts.Token); // ...and don't wait if not paused
int localValue = Interlocked.Increment(ref value);
Console.WriteLine($"Thread #{i}, Value: {localValue}");
}
}
catch (OperationCanceledException) // this exception is expected and benign
{
Console.WriteLine($"Thread #{i} Canceled");
}
})).ToArray();

// Start the threads
foreach (var thread in threads) thread.Start();

// Now lets pause and unpause the threads periodically some times
// We use the main thread (the current thread) as the controller
Thread.Sleep(500);
pts.IsPaused = false;
Thread.Sleep(1000);
pts.IsPaused = true;
Thread.Sleep(1000);
pts.IsPaused = false;
Thread.Sleep(1000);
pts.IsPaused = true;
Thread.Sleep(500);

// Finally cancel the threads and wait them to finish
cts.Cancel();
foreach (var thread in threads) thread.Join();

You may need to read this first, to get a grasp on the model used by the .NET platform for cooperative cancellation. Cooperative "pausation" is very similar.

How do I pause Threads properly with wait() and notify()

So given this is your Thread class:

public class MyThread extends Thread
{

First, you need an lock object. This object can be everything, and if you use an existing object this takes less memory. Also define a flag if the bot should be paused.

    public Object lock = this;
public boolean pause = false;

Now, define a pause() and continue() method for the thread. This sets the pause flag.

    public void pause ()
{
pause = true;
}

public void continue ()
{
pause = false;

Here you need to wake up the thread. Note the synchronized on the lock object so that you don't get an IllegalMonitorStateException.

        synchronized (lock)
{
lock.notifyAll();
}
}

No, define a method that automatically pauses the thread when it should be paused. You might call this at every moment when the thread can be paused.

    private void pauseThread ()
{
synchronized (lock)
{
if (pause)
lock.wait(); // Note that this can cause an InterruptedException
}
}

Now, you can define your thread in the run() method:

    public void run ()
{
task1();
task2();

pauseThread();

task3();
task4();
task5();
task6();
task7();

pauseThread();

task8();
task9();
task10();
}
}

How to pause all running threads? and then resume?

You can't suspend a thread execution by invoking wait() on it. wait() suspend the current thread until another thread calls notify() or notifyAll() on the same object the previous thread called wait() on. Moreover, in order to call wait(), notify() or notifyAll() on an object, the calling thread must hold that object's monitor by doing

synchronized(object) {
object.wait();
}

In order to suspend your counting, you need a flag and provide two methods to suspend and resume your counting. Something like:

class FirstCountDown extends SwingWorker<Integer, Integer> {

private _suspended = false;

public synchronized void suspend() { _suspended = true; notify(); }
public synchronized void resume() { _suspended = false; notify(); }

public Integer doInBackground() {
for(int i=0; i<1000; i++) {
synchronized(this) {
while (_suspended) {
wait(); // The current thread will block until some else calls notify()
// Then if _suspended is false, it keeps looping the for
}
}
CountDown.count1.setText(String.valueOf(1000-i));
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
}

how to pause/resume a thread

Maybe the ManualResetEvent is a good choice.
A short example:

private static EventWaitHandle waitHandle = new ManualResetEvent(initialState: true); 

// Main thread
public void OnPauseClick(...) {
waitHandle.Reset();
}

public void OnResumeClick(...) {
waitHandle.Set();
}

// Worker thread
public void DoSth() {
while (true) {
// show some random text in a label control (btw. you have to
// dispatch the action onto the main thread)
waitHandle.WaitOne(); // waits for the signal to be set
}
}

How to Pause and Resume a Thread in Java from another Thread

You can't definitively pause one thread from another in the way you seem to want.

What you need to do instead, is signal that the other thread should stop, by setting some sort of flag. The thread in question must have logic to check this flag and pause its work when that happens.

So in this particular case, perhaps change MyThread as follows:

class MyThread extends Thread {

private volatile boolean running = true; // Run unless told to pause

...

@Override
public void run()
{
for(int i=0 ; ; i++)
{
// Only keep painting while "running" is true
// This is a crude implementation of pausing the thread
while (!running)
yield;

area.setText(i+"");
}

public void pauseThread() throws InterruptedException
{
running = false;
}

public void resumeThread()
{
running = true;
}

}

This is a crude example that for brevity uses a sort of spinlock rather than proper monitor-based sleeping. Hopefully though it communicates the idea of how you use a flag to control the pausing of the thread.

Note that if you were doing some long-running set of steps within the block, instead of just the setText call, it would be good practice to check Thread.currentThread().interrupted() between each of the steps - and exit the loop if the itnerrupt flag is set. This is broadly what the built-in blocking methods (e.g. I/O) do so that they can be interrupted by other threads - since the running flag is only checked one per loop, it doesn't do much good to set it if each loop takes 20 minutes.



Related Topics



Leave a reply



Submit