Java concurrency: resettable enabled/disabled wait condition - java

I want to let a thread sleep until a certain condition becomes off. Basically, I need three operations:
enable(): enable sleeping mode (do nothing if already enabled)
disable(): disable sleeping mode (do nothing if already disabled)
await(): wait until sleeping mode becomes disabled (or return immediately if the sleeping mode was already disabled) or the thread becomes interrupted (InterruptedException is thrown)
With this, thread A calls enable(). Now thread B calls await() and goes to sleep until thread A (or another one) calls disable(). This cycle can be repeated.
I know this can be quite easily done with wait() and notify(), but I am wondering if JDK8 has such functionality built-in?
The closest I could find is was a CountdownLatch(1), unfortunately the implementation is not resettable.
Basically, I just want to call enable()/disable() and await(), while all concurrency concepts are abstracted in the implementation (though await() should throw InterruptedException, which is unavoidable).

You could use Condition :
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Switch {
private final Lock lock = new ReentrantLock();
private final Condition on = lock.newCondition();
private final Condition off = lock.newCondition();
private volatile boolean state = true;
public void enable() {
try {
lock.lock();
state = true;
on.signalAll();
} finally {
lock.unlock();
}
}
public void disable() {
try {
lock.lock();
state = false;
off.signalAll();
} finally {
lock.unlock();
}
}
public void await() {
try {
lock.lock();
while(!state) {
try {
off.await();
} catch (InterruptedException e) {
throw new RuntimeException("waiting interrupted.");
}
}
} finally {
lock.unlock();
}
}
}

Another possible implementation of Switch:
public class Switch {
private final AtomicBoolean state = new AtomicBoolean();
public void enable() {
state.set(true);
}
public void disable() {
if (state.compareAndSet(true, false)) {
synchronized (state) {
state.notifyAll();
}
}
}
public void await() throws InterruptedException {
if (state.get()) {
synchronized (state) {
while (state.get()) {
state.wait();
}
}
}
}
}

enable(): enable sleeping mode (do nothing if already enabled)
disable(): disable sleeping mode (do nothing if already disabled)
do nothing if already enabled (disabled) is a bad design, which can lead to subtle bugs which are hard to reproduce and discover. For example, let sleeping mode is disabled, and one thread calls disable() and the other calls enable(). Depending on which call is made first, the mode will stay enabled or disabled forever. To make execution more deterministic, enabling and disabling must be counted, and the final state will be determined (disabled).
Instead, your threads should exchange tokens which do not mask each other. Besides CountdownLatch, (which effectively is a counter of prohibitions), JDK has CyclicBarrier and Phaser, which are resettable counters of prohibitions, and Semaphore, which is a counter of permissions.
UPDT
this implementation may work (I did not tested it):
Phaser p = new Phaser(1);
public void await() {
p.arriveAndAwaitAdvance();
}
public void enable() {
p.register();
}
public void disable() {
p.arriveAndDeregister();
}
N sequential calls to enable() require the same number of disable() to pass the awaiting thread.

You could use a Semaphor too :
import java.util.concurrent.Semaphore;
public class Switch {
private Semaphore semaphore = new Semaphore(1);
public void enable() {
synchronized(this) {
semaphore.drainPermits(); // 0
semaphore.reducePermits(1); // -1 or 0
}
}
public void disable() {
semaphore.release(2); // 1 or 2
}
public void await() throws InterruptedException {
semaphore.acquire();
semaphore.release();
}
}

Related

IllegalMonitorStateException: object not locked by thread before wait()

I know that there are a lot of similar questions, but no one helped me. I am getting IllegalMonitorStateException: object not locked by thread before wait() when I try to pause the thread.
Here is my initialization method:
// called only once in constructor; the variables are global ( private Thread ... )
public void init() {
recordingThread = new Thread(new Runnable() {
#Override
public void run() {
isNewRecordingThread= false;
record();
}
});
recognitionThread = new Thread(new Runnable() {
#Override
public void run() {
isNewRecognition= false;
recognize();
}
});
...
}
startRecording method:
private synchronized void startRecording(Thread recordingThread) {
if(isNewRecordingThread){
recordingThread.start();
return;
}
recordingThread.notify();
}
startRecognition method:
private synchronized void startRecognition(Thread recognitionThread) {
shouldContinueRecognition = true;
if(isNewRecognition){
recognitionThread.start();
return;
}
recognitionThread.notify();
}
And the stopping method where I actually get the error:
private synchronized void stopRecordingAndRecognition(Thread recordingThread, Thread recognitionThread) {
try{
if (recordingThread != null && recordingThread.isAlive()) {
recordingThread.wait();
}
if (recognitionThread != null && recognitionThread.isAlive()) {
recognitionThread.wait();
}
} catch (InterruptedException e){
Log.d("TESTING","InterruptedException e= "+e);
}
}
"object not locked by thread before wait()"
Think, what object is meant in this message? That very object for which wait() is applied:
recordingThread.wait();
that is, recordingThread.
synchronized void stopRecordingAndRecognition is irrelevant because it locks this object, and not recordingThread.
So, there are 2 solutions:
force methods to synchronize on recordingThread
embed synchronized methods into the class of recordingThread
"The goal is to start thread, pause it and after resume"
Pausing and resuming threads in Java is a bad practice because leads to subtle and hard to debug errors.
The only reliable way to stop/resume some computational process is to split this process into parts, process that parts in a loop, and before the start of processing the next part, checking if processing is allowed.
As an evolution of this approach, each part is formed as a Runnable and is submitted to a single-threaded Executor. Instead of stop and resume the Executor, producer thread(s) simply stop and resume submitting the partial tasks to the executor.
If (some) parts can be processed in parallel, then multithreaded executor can be used, but it requires coordination between submitting particular tasks.
The goal is to start thread, pause it and after resume
Here is a code snippet that I use for suspending and resuming a thread.
public class ThreadStatus {
private boolean paused;
private final String threadName;
private final ReentrantLock lock;
private final Condition condition;
public ThreadStatus (String name) {
threadName = name;
lock = new ReentrantLock();
condition = lock.newCondition();
paused = false;
}
// check for the thread to be paused
public void checkForPause() {
lock.lock();
try {
while (paused) {
condition.await();
}
} catch (InterruptedException ie) {
// interrupted
} finally {
lock.unlock();
}
}
// Pause the thread
public void pause() {
lock.lock();
try {
paused = true;
} finally {
lock.unlock();
}
}
// Resume the thread
public void resume() {
lock.lock();
try {
paused = false;
condition.signalAll();
} finally {
lock.unlock();
}
}
#Override
public String toString() {
return threadName;
}
}
If you need you could implement isStopped() or isRunning() similarly.
final ThreadStatus threadStatus = new ThreadStatus("Thread-A");
In the client code, call threadStatus.checkForPause() at the relevant point. For example, if you have some repeated processings inside a loop, you can do something like -
while (!threadStatus.isStopped()) {
threadStatus.checkForPause();
// do your processing here
}

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

I want to have a class that starts a Thread and provides methods to pause and continue this Thread. My first approach was to have flag, which loops a sleep method as long as the value is true. Something like :
public class Bot {
private Thread t ;
private boolean isPaused;
public Bot(){
t = new Thread(new Runnable(){
#Override
public void run() {
while (true) {
System.out.println("Hi");
while(isPaused){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
t.start();
}
public void pauseBot(){
isPaused = true;
}
public void continueBot(){
isPaused = false;
}
}
But since the Thread is still running and wasting CPU, I dont find this to be a good solution. How would this look with wait() and notify().
I had a look at various tutorials about that topic but somehow I couldnt apply them to my issue.
Everytime I tried it I either got IllegalMonitorStateException or the code stopped my whole application and not just the Thread I wanted to be stopped.
Another question I have is: How do prevent the Thread from beeing paused at a critical moment e.g.
Runnable r = new Runnable(){
#Override
public void run() {
while(true){
task1();
task2();
//Thread mustn't be stopped from here....
task3();
task4();
task5();
task6();
task7();
//... to here
task8();
task9();
task10();
}
}
};
Because when task3() .... task7() deal with something that would expire while the Thread is paused there must be a way to let the Thread finish task7() until it pauses.
I hope you can help me with my issue.
Thanks in advance,
Flo
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();
}
}

Java Multithreading doesn't seem to be correctly working

I have a class which processes something. I'm trying to run a number of instances of this class in parallel.
However, I'm not sure if in TaskManager.startAll(), when I call r.go(), whether this would cause r to start running in its own thread, or within the main thread?
The total execution time that I'm getting seems to be very high, and despite my attempts at optimizing, nothing seems to be having any effect. Also, if I run a profiler on my project in Netbeans, it shows all the threads as sleeping. So I'd like to know if I'm doing something wrong?
This is the structure of the class:
public class TaskRunner implements Runnable {
private boolean isRunning = false;
public void run() {
while(true) {
while (! running) {
try {
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
process();
}
}
public void go() {
isRunning = true;
}
public void stop() {
isRunning = false;
}
private void process() {
//Do some number crunching and processing here
}
}
Here's how these are being run / managed:
public class TaskManager {
private ArrayList<TaskRunner> runners = new ArrayList<>();
public TaskManager() {
for (int i = 0; i < 10; i++) {
TaskRunner r = new TaskRunner();
new Thread(r).start();
runners.add(r);
}
}
public void startAll() {
for (TaskRunner r : runners) {
r.go();
}
}
}
Indeed, you are not "doing it right." If you want to create a multi-threaded Java application, the place to start is with the java.util.concurrent package.
It appears from your code that you want to run ten tasks in parallel. I assume that after "number crunching and processing," you'll want to aggregate the results and do something with them in the main thread. For this, the invokeAll() method of ExecutorService works well.
First, implement Callable to do the work you show in your process() method.
final class YourTask implements Callable<YourResults> {
private final YourInput input;
YourTask(YourInput input) {
this.input = input;
}
#Override
public YourResults call()
throws Exception
{
/* Do some number crunching and processing here. */
return new YourResults(...);
}
}
Then create your tasks and run them. This would take the place of your main() method:
Collection<Callable<YourResults>> tasks = new List<>(inputs.size());
for (YourInput i : inputs)
tasks.add(new YourTask(i));
ExecutorService workers = Executors.newFixedThreadPool(10);
/* The next call blocks while the worker threads complete all tasks. */
List<Future<YourResult>> results = workers.invokeAll(tasks);
workers.shutdown();
for (Future<YourResult> f : results) {
YourResult r = f.get();
/* Do whatever it is you do with the results. */
...
}
However, I'm not sure if in TaskManager.startAll(), when I call r.go(), whether this would cause r to start running in its own thread, or within the main thread?
So my first comment is that you should make isRunning be volatile since it is being shared between threads. If the threads are not starting when it goes to true (or seem to be delayed in starting) then I suspect that's your problem. volatile provides memory synchronization between the threads so the thread that calls go() and makes a change to isRunning will be seen immediately by the thread waiting for the change.
Instead of spinning like this, I would use wait/notify:
// this synchronizes on the instance of `TaskRunner`
synchronized (this) {
// always do your wait in a while loop to protect against spurious wakeups
while (!isRunning && !Thread.currentThread().isInterrupted()) {
try {
// wait until the notify is called on this object
this.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
Then in the go() method you should do the following. stop() would be similar.
public void go() {
synchronized (this) {
isRunning = true;
this.notifyAll();
}
}
Notice that you should handle thread interrupts carefully. Test for isInterrupted() in the while running loop and re-interrupt a thread when InterruptedException is thrown is always a good pattern.
The total execution time that I'm getting seems to be very high, and despite my attempts at optimizing, nothing seems to be having any effect. Also, if I run a profiler on my project in Netbeans, it shows all the threads as sleeping.
So although the threads are mostly sleeping, they are still each looping 1000 times a second because of your Thread.sleep(1). If you increased the time sleeping (after making isRunning be volatile) they would loop less but the right mechanism is to use the wait/notify to signal the thread.
Awful solution, terrible. first I highly recommend you start reading some tutorial like [this]
Second, if threads should wait for a signal to go for some job, so why just don't you wait them!!!!!, something like this
import java.util.ArrayList;
public class TaskManager
{
//////////////////////
public volatile static Signal wait=new Signal();
//////////////////////
private ArrayList<TaskRunner> runners = new ArrayList<>();
public TaskManager()
{
for (int i = 0; i < 10; i++)
{
TaskRunner r = new TaskRunner();
new Thread(r).start();
runners.add(r);
}
try {
Thread.sleep(1000);
startAll();
Thread.sleep(1000);
pauseAll();
Thread.sleep(1000);
startAll();
Thread.sleep(1000);
haltAll();System.out.println("DONE!");
}catch(Exception ex){}
}
public void startAll()
{
synchronized(wait){
wait.setRun(true);;
wait.notifyAll();
}
}
public void pauseAll(){
wait.setRun(false);
}
public void haltAll(){
for(TaskRunner tx:runners){tx.halt();}
}
public static void main(String[] args) {
new TaskManager();
}
}
class TaskRunner implements Runnable
{
private Thread thisThread;
private volatile boolean run=true;
public void run()
{
thisThread=Thread.currentThread();
while(run){
if(!TaskManager.wait.isRun()){
synchronized(TaskManager.wait)
{
if(!TaskManager.wait.isRun()){
System.out.println("Wait!...");
try
{
TaskManager.wait.wait();
}
catch (Exception e)
{
e.printStackTrace();
break;
}
}
}}
process();
}
}
private double r=Math.random();
private void process(){System.out.println(r);try {
Thread.sleep(10);
} catch (Exception e) {
// TODO: handle exception
}}
public void halt(){run=false;thisThread.interrupt();}
}
class Signal{
private boolean run=false;
public boolean isRun() {
return run;
}
public void setRun(boolean run) {
this.run = run;
}
}
in above sample, all runners works till the Signal run boolean is true, and simple TaskManager class set tit as false for every time it needs to pause the threads. and about the halt, it just set the shutdown(run) flag to false, and also interrupt the thread because of if thread is in wait state.
I hope I could prove your solution is like dream-on story, and also could explained enough about my solution.
have a good parallel application :)

More efficient way for pausing loop wanted

Is it possible to rewrite this code for better working with processor?
I have a class, which does some tasks with fixed periodicy in a separate thread. Sometimes this process can be paused and resumed. Currently I am using a flag for pausing, it works fine, but loop in this way still loads processor when process is paused. Is it possible to fix this?
private boolean mIsCanceled = false;
private boolean mIsPaused = true; // TODO more efficient for processor way of pausing is required
private final Thread mTimerThread = new Thread(new Runnable() {
#Override
public void run() {
while(!mIsCanceled){
try {
Thread.sleep(UPDATE_PERIOD);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (!mIsPaused){
doStep();
}
}
}
});
public MyClass(){
mTimerThread.start();
}
private void pause(){
mIsPaused = true;
}
private void resume(){
mIsPaused = false;
}
private void doStep(){
// Some code
}
Please just provide alternative implementation of my code.
P.S. The environment is Android OS 2.2+
The tools available are:
wait/notify - we are all trying to get away from this archaic system.
Semaphores - once your thread has grabbed it you hold it until release so grabbing it again does not block. This means you cannot pause from within your own thread.
CyclicBarrier - Must be created anew each time it is used.
ReadWriteLock - My favorite. You can have as many threads pausing you as you like and you will only resume when all of them have called resume. You can even pause yourself if you wish.
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* PauseableThread is a Thread with pause/resume and cancel methods.
*
* The meat of the process must implement `step`.
*
* You can either extend this and implement `step` or use the factory.
*
* Note that I cannot extend Thread because my resume will clash with Thread's deprecated one.
*
* Usage: Either write a `Stepper` and run it in a `PausableThread` or extend `PausableThread` and call `blockIfPaused()` at appropriate points.
*/
public abstract class PauseableThread implements Runnable {
// The lock.
// We'll hold a read lock on it to pause the thread.
// The thread will momentarily grab a write lock on it to pause.
// This way you can have multiple pausers using normal locks.
private final ReadWriteLock pause = new ReentrantReadWriteLock();
// Flag to cancel the wholeprocess.
private volatile boolean cancelled = false;
// The exception that caused it to finish.
private Exception thrown = null;
#Override
// The core run mechanism.
public void run() {
try {
while (!cancelled) {
// Block here if we're paused.
blockIfPaused();
// Do my work.
step();
}
} catch (Exception ex) {
// Just fall out when exception is thrown.
thrown = ex;
}
}
// Block if pause has been called without a matching resume.
private void blockIfPaused() throws InterruptedException {
try {
// Grab a write lock. Will block if a read lock has been taken.
pause.writeLock().lockInterruptibly();
} finally {
// Release the lock immediately to avoid blocking when pause is called.
pause.writeLock().unlock();
}
}
// Pause the work. NB: MUST be balanced by a resume.
public void pause() {
// We can wait for a lock here.
pause.readLock().lock();
}
// Resume the work. NB: MUST be balanced by a pause.
public void resume() {
// Release the lock.
pause.readLock().unlock();
}
// Stop.
public void cancel() {
// Stop everything.
cancelled = true;
}
// start - like a thread.
public void start() {
// Wrap it in a thread.
new Thread(this).start();
}
// Get the exceptuion that was thrown to stop the thread or null if the thread was cancelled.
public Exception getThrown() {
return thrown;
}
// Create this method to do stuff.
// Calls to this method will stop when pause is called.
// Any thrown exception stops the whole process.
public abstract void step() throws Exception;
// Factory to wrap a Stepper in a PauseableThread
public static PauseableThread make(Stepper stepper) {
StepperThread pauseableStepper = new StepperThread(stepper);
// That's the thread they can pause/resume.
return pauseableStepper;
}
// One of these must be used.
public interface Stepper {
// A Stepper has a step method.
// Any exception thrown causes the enclosing thread to stop.
public void step() throws Exception;
}
// Holder for a Stepper.
private static class StepperThread extends PauseableThread {
private final Stepper stepper;
StepperThread(Stepper stepper) {
this.stepper = stepper;
}
#Override
public void step() throws Exception {
stepper.step();
}
}
// My test counter.
static int n = 0;
// Test/demo.
public static void main(String[] args) throws InterruptedException {
try {
// Simple stepper that just increments n.
Stepper s = new Stepper() {
#Override
public void step() throws Exception {
n += 1;
Thread.sleep(10);
}
};
PauseableThread t = PauseableThread.make(s);
// Start it up.
t.start();
Thread.sleep(1000);
t.pause();
System.out.println("Paused: " + n);
Thread.sleep(1000);
System.out.println("Resuminng: " + n);
t.resume();
Thread.sleep(1000);
t.cancel();
} catch (Exception e) {
}
}
}
Edit: Code modified to be of more general use.
Your best options are to either use wait()/notify() or to simply switch to ScheduledExecutorService
Proper wait()/notify() usage can be tricky. I highly recommend "Java Concurrency in Practice" to learn more about threading.
I believe the best way here would be to use Thread.wait for the waiting thread instead of sleeping, and use Thread.notify in the thread you are waiting for.
More info here:
http://www.javamex.com/tutorials/synchronization_wait_notify.shtml
You can improve efficiency drastic by using a monitor instead of sleeping the thread. You just make blocks in your code with a keyword synchronized. And an final Object that's acts the monitor. Look uP more in the API on monitors.

Waiting for all Runnables submitted to SWT UI thread with Display::asyncExec() to finish

Is there a way to wait for all Runnables submitted to the SWT UI Thread via asyncExec(...) to finish?
Background:
I have a long-running operation, which among other things is triggering events that in turn submit Runnables to the SWT UI thread via the asyncExec(...) instance method of Display.
The progress of the long-running operation is shown in a ProgressMonitorDialog, and I would like to close the dialog only after the UI thread has finished executing the Runnables.
Changing the calls from asyncExec(...) to syncExec(...) is not an option, as the latter is not desired when the events are triggered from other contexts.
org.eclipse.swt.widgets.Display.readAndDispatch() will process an event from the event queue and return false if there are no more events to process. But you probably don't want to use this as it processes an event.
asyncExec(*) is a FIFO queue (although OS graphics events supersede the asyncExecs), so you could do most of your long-running op processing and then place a final asyncExec in the queue:
final boolean[] done = new boolean[1];
Runnable r = new Runnable() {
public void run() {
done[0] = true;
}
};
// now wait for the event somehow. The brute force method:
while (!done[0]) {
Thread.sleep(200);
}
In theory, all of the other asyncExecs spawned from your long running op will be finished by the time you get to the last one.
EDIT: potential other option
Create your own org.eclipse.core.runtime.jobs.Job and then join() it at the end:
public static class RefCountJob extends Job {
public RefCountJob() {
super("REF_COUNT");
}
int count = 0;
public void increment() {
count++;
}
public void decrement() {
count--;
}
#Override
protected IStatus run(IProgressMonitor monitor) {
monitor.beginTask("WAITING", IProgressMonitor.UNKNOWN);
while (count > 0) {
Thread.sleep(200);
monitor.worked(1);
}
monitor.done();
return Status.OK_STATUS;
}
}
To use it, increment() it every time you are going to fire off events, and have them decrement it when they're done (You have to make sure they decrement it no matter what exception is thrown :-)
RefCountJob ref = new RefCountJob();
// ... do stuff, everybody increments and decrements ref
ref.increment();
// ... do more stuff
ref.increment();
// at the end of your long-running job
ref.schedule();
ref.join();
Thanks, I ended up with the following. I think it is a pretty clean solution. By the way I would upvote your answer if I had enough reputation for that :)
public class SWTThreadingUtils
{
public static void waitForAsyncExecsToFinish(Display display)
{
Object waitObj = new Object();
display.asyncExec(new DummyRunnable(waitObj));
synchronized (waitObj)
{
try {
waitObj.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
private static class DummyRunnable implements Runnable
{
private Object waitObj;
public DummyRunnable(Object waitObj)
{
this.waitObj = waitObj;
}
#Override
public void run()
{
synchronized (waitObj)
{
waitObj.notify();
}
}
}
}

Categories