Spontaneous execution of code in periodically running thread - java

I have a thread which executes code periodically, e. g. every 10 seconds. I'd like to have the option to also invoke the same code in a spontaneous way and not have to wait 10 seconds. But the code of the automatic and spontaneous execution must never run concurrently, instead they should run in sequence if the user presses the execute button while the thread is invoking the same method.
Does anyone know a good pattern or even a class that can address this kind of requirement?
First thing that comes to mind would be to make the work method synchronized. But in that case the manual execution (e. g. button press) is blocked and has to wait until the method in the thread is finished. Is there a better approach without blocking?
Example:
public class Executor extends Thread {
// endless loop, executes work method periodically with pause inbetween
#Override
public void run() {
while( true) {
work( "automatic");
pause(10000);
}
}
// Working method that's executed periodically or manually
private synchronized void work( String text) {
System.out.println( "Working " + text + " " + System.currentTimeMillis());
}
// helper method that pauses the thread
private static void pause( long sleepMs) {
try {
Thread.sleep(sleepMs);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// start automatic execution
Executor executor = new Executor();
executor.start();
// pause a while
pause(1000);
// manual execution
executor.work( "manual");
}
}
Edit: Solution for my requirement:
public class ScheduledExecutor {
public static void main(String[] args) throws InterruptedException {
ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(1);
executor.scheduleWithFixedDelay(new Work("auto"), 0, 10, TimeUnit.SECONDS);
Thread.sleep(1000);
executor.execute(new Work("manual"));
}
public static class Work implements Runnable {
String text;
public Work(String text) {
this.text = text;
}
#Override
public void run() {
System.out.println("Working " + text + " " + System.currentTimeMillis());
}
}
}

I would create a new, single-thread executor service:
ExecutorService executorService = Executors.newFixedThreadPool(1);
Then, I would set up a timer that feeds the executorService a task once every 10 seconds.
new Timer(10000, new ActionListener {
public void actionPerformed(ActionEvent evt) {
executorService.execute(() -> doWhatever());
}
}).start();
Finally, you can call executorService.execute(() -> doWhatever()); in your button press handler, or wherever else you want in your code.
Only one activation of doWhatever() will run at a time because the executorService has only one thread on which to run them. And, your button press handler will never have to wait, because it does nothing but put a new object on a queue.

I have a thread which executes code periodically, e. g. every 10 seconds. I'd like to have the option to also invoke the same code in a spontaneous way and not have to wait 10 seconds.
A simple way to do this in your code is not to pause by using Thread.sleep(...) but rather do wait(...). Then whenever you want the command to wakeup and run manually it just does a notify().
So you code would look something like:
while( true) {
work( "automatic");
synchronized (this) {
try {
// wait for a bit but allow someone else to awake us to run manually
wait(10000);
} catch (InterruptedException ie) {
// always a good pattern
Thread.currentThread().interrupt();
return;
}
}
}
Then when you want to have it run manually you do:
synchronized (executor) {
executor.notify();
}
The notify will awaken the thread immediately so that it can run it's task. The work method then does not need to be synchronized because only the Executor thread is running it.
NOTE: As pointed out by #shinobi, using wait() like this could suffer from spurious wake-ups which can happen with certain OS thread implementations.
Lastly, it is a better practice to make Executor implement Runnable as opposed to extending Thread.

Share a semaphore between the server thread (the one that executes the task) and client threads (the ones that need to trigger immediate execution):
Semaphore sem = new Semaphore( 0 );
The server thread needs to execute the following code (note that it's an endless loop — you'll likely want to plug-in your program termination check as the condition to while()):
while( true ) {
try {
sem.tryAcquire( 10, TimeUnit.SECONDS );
} catch( InterruptedException e ) {
continue;
}
runTask();
sem.drainPermits();
}
Then, in order to trigger immediate execution, the client thread needs to do:
sem.release();
Thus, the server thread will execute the task upon either acquiring a permit from the semaphore as soon as a client thread releases one (triggered immediate execution,) or timing-out in Semaphore.tryAcquire() (periodic executions 10s apart, end-to-start.) Having executions 10s apart start-to-start will take some slightly more involved logic, as well as keeping track of last execution's starting time, but the basic idea remains the same.
You need to drain the permits each time in order to avoid multiple back-to-back executions of the task, in cases where it might be triggered for immediate execution while still being executed.

Related

What are the thread command alternatives in Java?

I am dealing with threads and I want to run this code whenever I open Cal_JInternalFrame. It runs the fist time, but whenever I reopen the frame, it doesn't run again. I use t1.interrupted() at exit time of the whole application. The code is:
Thread t1 = new Thread( new Runnable() {
#Override
public void run() {
while ( !t1.isInterrupted() ) {
// ......... Oil Calculation Thread ...
int price = (Integer.parseInt(jLabel22.getText()));
int qty = (Integer)jSpinner8.getValue();
int totalOil =qty * price;
jTextField19.setText(String.valueOf(totalOil));
}
}
});
t1.start() is in the constructor of the main frame.
The thread primitive methods destroy(), stop(), resume(), and suspend() have been deprecated, so I can't use those. How can I stop and resume a thread now? And if my thread t1 is interrupted, how can it be resumed or run again?
Threads cannot be re-used. For tasks that require to be executed on a separate thread at different times, use a single thread executor.
It seems like you need a worker thread. Since standard threads are not reusable without extra work, we use worker threads to manage tasks that should be executed multiple times.
ExecutorService executors = Executors.newSingleThreadExecutor();
With this, you can reuse a single thread to execute code multiple times. It also allows you to make asynchronous callbacks using Future like this:
class Demo {
static ExecutorService executor = Executors.newSingleThreadExecutor();
public static void main(String[] args) {
Future<String> result = executor.submit(new Callable<String>() {
public String call() {
//do something
return "Task Complete";
}
});
try {
System.out.println(result.get()); //get() blocks until call() returns with its value
}catch(Exception e) {
e.printStackTrace();
}
}
}
You can now re-use executor for the task that you want. It accepts Runnable through it's execute(Runnable) method.
I see you're using Swing. Post all swing code to the Event Dispatch Thread using EventQueue.invokeLater(Runnable). getText() and setText() should be called on the Event Dispatch Thread to avoid inconsistancies.
How can I stop and resume a thread now?
You can't. Instead, you need to make your thread stop and resume itself. For example:
private boolean wake;
public synchronized void wakeup() {
this.wake = true;
this.notify();
}
public void run() {
while ( !t1.isInterrupted() ) {
// do stuff ...
wake = false;
synchronized (this) {
while (!wake) {
try {
this.wait();
} catch (InterruptedException ex) {
t1.interrupt(); // reset the interrupted flag
}
}
}
}
}
When some other thread wants to get this one to do something, the calls the wakeup() method on the extended runnable object.
And if my thread t1 is interrupted, how can it be resumed or run again?
As you have written it, No. Once the thread returns from the run() method call, it cannot be restarted. You would need to create and start a brand new Thread.
However, what you are trying to do is unsafe. As #Erwin points out, it is not safe for the t1 thread to be calling methods on Swing objects such as jTextField19. You should only call methods on Swing objects from the Swing event dispatching thread.
Reference:
Concurrency in Swing

How to manage worker thread lifecycles when main Java thread terminates?

I want to achieve the following: When my application starts, the main thread will start 1+ worker threads that should run in the background, and periodically do things behind the scenes. These should not block the main thread: once main starts the workers, it continues doing its own thing until:
The main thread finishes (normal application termination) - in the case of a command-line utility this is when the end of the main(String[]) method is reached; in the case of a Swing GUI it could be when the user selects the File >> Exit menu, etc.
The operating system throws a kill command (SIGKILL, etc.)
An unexpected, uncaught exception occurs in the main thread, effectively killing it (this is just an unpolite version of #1 above)
Once started/submitted from the main thread, I want all the worker threads (Runnables) to essentially have their own life cycle, and exist independently of the main thread. But, if the main thread dies at any time, I want to be able to block (if at all possible) the main thread until all the workers are finished shutting down, and then "allow" the main thread to die.
My best attempt so far, although I know I'm missing pieces here and there:
public class MainDriver {
private BaneWorker baneWorker;
private ExecutorService executor = Executors.newCachedThreadPool();
public static void main(String[] args) {
MainDriver driver = new MainDriver();
driver.run();
// We've now reached the end of the main method. All workers should block while they shutdown
// gracefully (if at all possible).
if(executor.awaitTermination(30, TimeUnit.SECONDS))
System.out.println("Shutting down...");
else {
System.out.println("Forcing shut down...");
executor.shutdownNow();
}
}
private void run() {
// Start all worker threads.
baneWorker = new BaneWorker(Thread.currentThread());
// More workers will be used once I get this simple example up and running...
executor.submit(baneWorker);
// Eventually submit the other workers here as well...
// Now start processing. If command-line utility, start doing whatever the utility
// needs to do. If Swing GUI, fire up a parent JFrame and draw the application to the
// screen for the user, etc.
doStuff();
}
private void doStuff() {
// ??? whatever
}
}
public class BaneWorker implements Runnable {
private Timer timer;
private TimerTask baneTask;
private Thread mainThread;
public BaneWorker(Thread mainThread) {
super();
this.mainThread = mainThread;
}
#Override
public void run() {
try {
timer = new Timer();
baneTask = new TimerTask() {
#Override
public void run() {
System.out.println("When the main thread is ashes...");
}
};
// Schedule the baneTask to kick off every minute starting now.
timer.scheduleAtFixedRate(baneTask, new Date(), 60 * 1000);
} catch(InterruptedException interrupt) {
// Should be thrown if main thread dies, terminates, throws an exception, etc.
// Should block main thread from finally terminating until we're done shutting down.
shutdown();
}
}
private void shutdown() {
baneTask.cancel();
System.out.println("...then you have my permission to die.");
try {
mainThread.join();
} catch(InterruptedException interrupt) {
interrupt.printStackTrace;
}
}
}
Am I on-track or way off-base here? What do I need to change to make this work the way I need it to? I'm new to Java concurrency and am trying my best to use the Concurrency API correctly, but stumbling around a bit. Any ideas? Thanks in advance!
The main thread must signal the worker threads to terminate (generally this is achieved just by using a flag) and then it should call join on every thread to wait for their termination. Have a look here: Java: How to use Thread.join
You can use Runtime.addShutdownHook to register an un-started thread that is executed when a JVM is terminated, the system is shutting down etc. This code can do some cleanup itself, or perhaps notify running daemon threads to finish their work. Any such cleanup code must be relatively fast, because on many systems programs have only a limited time to do cleanup before they're forcibly terminated.
Perhaps you could also consider making your background thread daemon threads. Then they will not block the JVM when main finishes and will be still running during the clean-up phase.
Note that you can't intercept SIGKILL - this signal is designed to be unavoidable and immediate. But it should work with SIGTERM, SIGHUP and similar signals.
Update: You can easily create ExecutorServices that run daemon threads. All you need is to create a proper ThreadFactory:
public static class DaemonFactory
implements ThreadFactory
{
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
}
than you create an ExecutorService like
public static void main(String argv[])
throws Exception
{
ExecutorService es
= Executors.newCachedThreadPool(new DaemonFactory());
// ^^^^^^^^^^^^^^^^^^^
es.submit(new Callable<Object>() {
public Object call() throws Exception {
Thread.sleep(100);
System.err.println("Daemon: " +
Thread.currentThread().isDaemon());
return null;
}
});
// Without this, JVM will terminate before the daemon thread prints the
// message, because JVM doesn't wait for daemon threads when
// terminating:
es.awaitTermination(3, TimeUnit.SECONDS);
}
Concerning Thread.join(), you shouldn't try to use it on threads managed by an ExecutorService. It's the responsibility of the executor to manage them. You have no reliable way how to enumerate its threads, the executor can create and destroy threads depending on its configuration etc. The only reliable way is to call shutdown(); and then awaitTermination(...);.
If SIGKILL is a unix "kill -9" there's nothing you can do about it.
For graceful exits, use a try/catch/finally in your main. The catch will catch your exceptions and allow you to do what needs to be done (recover? abort?) The finally will give you the hook to spin down your threads gracefully.
Reviewing your code quickly, I don't see where you're keeping track of your thread instances. You'll need those if you're going to tell them to spin down.
psuedocode:
static Main(...) {
ArrayList threads = new ArrayList();
try {
for (each thread you want to spin up) {
threads.add(a new Thread())
}
}
catch { assuming all are fatal. }
finally {
for(each thread t in threads) {
t.shutdown();
t.join(); /* Be prepared to catch (and probably ignore) an exception on this, if shutdown() happens too fast! */
}
}

Prevent multiple asynchronous calls from being in flight simultaneously without blocking

Here's essentially my problem:
while (true) {
if (previous 'doWorkAsync' method is not still in flight) {
doWorkAsync() // this returns immediately
}
wait set amount of time
}
A couple solutions come to mind for me:
Block until doWorkAsync() completes. This is not desirable to me for a few reasons.
It (potentially) results in waiting longer than I really needed to in the 'wait some set amount of time' line (e.g. if doWorkAsync takes 5 seconds, and the set amount of waiting time is 10 seconds, this will result in 15 seconds of waiting between calls, which isn't what I wanted). Of course, I could account for this by waiting less time, but somehow it just feels clunky.
It also ties up this thread unnecessarily. Instead of waiting for this task to come back, this thread could handle other work, like making config updates so the next call to doWorkAsync() has fresh data.
Use a gating mechanism. The easiest implementation that comes to mind is a boolean, set before calls to doWorkAsync(), and unset when doWorkAsync() completes. This is essentially what I'm doing now, but I'm not sure if it's an anti-pattern??
Is #2 the right way to go, or are there better ways to solve this problem?
EDIT: If it helps, doWorkAsync() returns a ListenableFuture (of guava).
The original question may not have been 100% clear. Here's the crux. If the async request finishes before the given timeout, this code will always work. However, if the async task takes SET_AMOUNT_OF_TIME + epsilon to complete, then this code will sleep twice as long as necessary, which is what I'm trying to avoid.
The simplest way to do this is using the wait and notifyAll methods already in Java. All you need to do is use an AtomicBoolean as a flag and block on it until the another Thread tells you something has changed.
The difference between that and your approach is that a blocked thread doesn't do anything whereas a polling thread uses CPU time.
Here is a simple example using two Threads - the Runnable "First" is submitted and it waits on done until the Runnable "Second" notifies that it has changed the flag.
public class App {
private static final AtomicBoolean done = new AtomicBoolean(false);
private static final class First implements Runnable {
#Override
public void run() {
while (!done.get()) {
System.out.println("Waiting.");
synchronized (done) {
try {
done.wait();
} catch (InterruptedException ex) {
return;
}
}
}
System.out.println("Done!");
}
}
private static final class Second implements Runnable {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
return;
}
done.set(true);
synchronized (done) {
done.notifyAll();
}
}
}
public static void main(String[] args) throws InterruptedException {
final ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(new First());
Thread.sleep(1000);
executorService.submit(new Second());
executorService.shutdown();
}
}
The sleep calls are just to show that a task of arbitrary length can take place, obviously they are not required.
The thing to note is that First prints "waiting" every time it enters the loop and, if you run the code, it only prints it once. The second thing to note is that First reacts to the changing of the flag immediately as it is told to awake and recheck when the flag is changed.
I have used return in the InterruptedException blocks, you may want to used Thread.currentThread().interrupt() instead so that the process doesn't die if it's spuriously interrupted.
A more advanced approach is to use Lock and Condition
public class App {
private static final Lock lock = new ReentrantLock();
private static final Condition condition = lock.newCondition();
private static final class First implements Runnable {
#Override
public void run() {
lock.lock();
System.out.println("Waiting");
try {
condition.await();
} catch (InterruptedException ex) {
return;
} finally {
lock.unlock();
}
System.out.println("Done!");
}
}
private static final class Second implements Runnable {
#Override
public void run() {
lock.lock();
try {
Thread.sleep(1000);
condition.signalAll();
} catch (InterruptedException ex) {
return;
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) throws InterruptedException {
final ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(new First());
Thread.sleep(1000);
executorService.submit(new Second());
executorService.shutdown();
}
}
In this situation First acquires a lock on the Lock object the immediately calls await on the Condition. The releases the lock and blocks on the Condition.
Second then acquires a lock on the Lock and calls signalAll on the Condition which awakes First.
First then reacquires the lock and continues execution, printing "Done!".
EDIT
The OP would like to call the method doWorkAsync with a specified period, if the method takes less time than the period then the process has to wait. If the method takes longer then the method should be called again immediately after.
The task needs to be stopped after a certain time.
At no point should the method be running more than once simultaneously.
The easiest approach would be to call the method from a ScheduledExecutorService, the Runnable would wrap the method and call get on the Future - blocking the scheduled executor until it is done.
This guarantees that the method is called with at least WAIT_TIME_BETWEEN_CALLS_SECS delay.
Then schedule another task that kills the first one after a set time.
final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
final Future<?> taskHandle = scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
final ListenableFuture<Void> lf = doWorkAsync();
try {
doWorkAsync().get();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
} catch (ExecutionException ex) {
throw new RuntimeException(ex);
}
}
}, 0, WAIT_TIME_BETWEEN_CALLS_SECS, TimeUnit.SECONDS);
scheduledExecutorService.schedule(new Runnable() {
#Override
public void run() {
taskHandle.cancel(false);
}
}, TOTAL_TIME_SECS, TimeUnit.SECONDS);
The best solution would be call the raw Runnable on a ScheduledExecutorService rather than calling it on another executor and blocking on the ListenableFuture.
Think what you are looking for is The Reactor Pattern.
Is there a reason you don't want these things running at the same time? If what you want to do is chain them, you could use Futures. Akka has Composable Futures and mappable ones.

Properly writing task that ExecutorService.shutdownNow() can stop?

I have a processing loop of the form
while (true) {
doWork();
Thread.sleep(SLEEP_INTERVAL);
}
I want to make a Runnable out of this that can play well with ExecutorService and which will exit when ExecutorService.shutdownNow() is called.
I'm looking to write it this way:
public WorkerTask implements Runnable
{
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
doWork();
try {
Thread.sleep(SLEEP_INTERVAL);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
Simple testing shows it at least appearing to work in that the task gets interrupted and will exit and the ExecutorService will shut down, and appears to do so whether the interrupt arrives while doWork() is processing or during the sleep. (By varying how much work doWork() does and how big SLEEP_INTERVAL is I can pretty much control where the interrupt happens).
But when I google I see examples using Thread.interrupted() as well as Thread.currentThread().isInterrupted(). I understand that the former clears the interrupted flag while the latter leaves it, but is there any other difference I need to care about?
I also see versions where the result of Thread.currentThread().isInterrupted() or Thread.interrupted() is stored in a volatile variable and that variable is used as the while loop test condition. Is that just a style or is there a need to do that? In what I've written do I have to worry that somehow something can clear the interrupt flag between when it is set (whether by being received when the thread is live, or by my catching InterruptedException and reasserting the flag) and when Thread.currentThread().isInterrupted() is called in the loop test?
Your code looks fine to me. Introducing an additional volatile variable would be unnecessary complexity: the interrupt status does the job.
The recommended way, in Java Concurrency in Practice, to deal with interrupts in tasks is to either throw an InterruptedException (this is doable if the task is a Callable and not a Runnable), or to make sure the interrupt status is set and to exit from the task ASAP. Your code does that well.
Could you take a look at ScheduledExecutorService if it matches your requirements:
class BeeperControl {
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
public void beepForAnHour() {
final Runnable beeper = new Runnable() {
public void run() { System.out.println("beep"); }
};
final ScheduledFuture<?> beeperHandle =
scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
scheduler.schedule(new Runnable() {
public void run() { beeperHandle.cancel(true); }
}, 60 * 60, SECONDS);
}
}}
Basically you should take advantage of java.util.concurrent libraries here .You should submit your task via ExecutorService.submit()and then call blocking methods like Future.get() , then you can be sure that those methods will respond to interruption as soon as possible by throwing an ExecutionException() .You probably should get rid of that Thread.sleep() since it is doing nothing . You want to sniff an interrupt as quickly as possible .You possibly also want to wait for a timeout in case your task is doing something inifinitely . So if the task terminates with a TimeOutException , the task is cancelled via its Future.
I call cancel() unconditionally since cancelling a completed task has no effect.
In that case you can do some thing like :
public static void main(String[] args) {
WorkerTask runnable;
TimeUnit unit;
Future<?> task = executor.submit(workerTask);
try{
task.get(timeout,unit);
} catch(TimeoutException e){
}catch(ExecutionException e){
throw e.getCause();
} finally{
//Harmless if the task already completed
task.cancel(true);
}
}
}

how to stop a thread in a threadpool

I'm writing an application that spawns multiple concurrent tasks. I'm using a thread pool to implement that.
It may happen that an event occurs that renders the computations being done in the tasks invalid. In that case, I would like to stop the currently running tasks, and start new ones.
My problem: How do I stop the currently running tasks? The solution I implemented is to store a reference to the task thread and call interrupt() on this thread. In demo code:
public class Task implements Runnable {
private String name;
private Thread runThread;
public Task(String name) {
super();
this.name = name;
}
#Override
public void run() {
runThread = Thread.currentThread();
System.out.println("Starting thread " + name);
while (true) {
try {
Thread.sleep(4000);
System.out.println("Hello from thread " + name);
} catch (InterruptedException e) {
// We've been interrupted: no more messages.
return;
}
}
}
public void stop() {
runThread.interrupt();
}
public String getName() {
return name;
}
}
And the main method is:
public static void main(String args[]) {
executorService = Executors.newFixedThreadPool(2);
Task t1 = new Task("Task1");
Task t2 = new Task("Task2");
executorService.execute(t1);
executorService.execute(t2);
executorService.execute(new Task("Task3"));
executorService.execute(new Task("Task4"));
try {
Thread.sleep(12000);
t1.stop();
System.err.println("Stopped thread " + t1.getName());
Thread.sleep(8000);
t2.stop();
System.err.println("Stopped thread " + t2.getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Is this a good solution, or is there a better way to stop a running thread in a thread pool?
You can stop it by holding a reference to that future
Future<?> future = exec.submit( new Runnable() {
while (true){
try{
obj.wait();
} catch(InterruptedException e){
System.out.println("interrupted");
return;
}
}
});
future.cancel(true);
boolean is for - may interrupt if running.
I tested out and got an interrupted exception from that thread.
If you have cachedThreadPool you may want to double check that you catch the exception in your runnable, and then don't set back the flag interrupted, because your thread will run another future, if you set interrupt, the other queue future may not run.
The idea behind your approach is one of the several correct solutions. Dealing with InterruptedException gives a great rundown on how you should use the interrupt mechanism. This mechanism is mainly useful when you are long computations. One other thing to keep in mind is that it is possible for other libraries to spoil your interrupt mechanism by not doing what the guide says (not resetting the interrupt state when they haven't handled it etc).
Do note that your Task class isn't thread-safe. You could be stopping the task before saving the currentThread, which would give a NullPointerException.
A much simpler approach is to set a volatile boolean variable running and instead of a while(true) loop doing a while(running) approach (this is however much more general).
Another thing to look at is the FutureTask mechanism, as this already has a canceling mechanism that uses the interrupt mechanism.
In your overridden run() method you loop forever with while(true). The standard behaviour would be to have a boolean runIndicator which the run() method sets to true when it starts, and your loop should then be while(runIndicator). Your stop() method should simple set runIndicator = false so the next iteration of the loop will fall out.
executorService.shutdown() and executorService.shutdownNow() should be used to shutdown the thread pool to gracefully exiting the application. See ExecutorService.
See Qwerky's answer for ending the currently running thread.

Categories

Resources