ScheduledExecutorService only runs once - java

I want a process to run after I start my webservice, and then every 30 minutes or so afterwards, (I'm testing it with a smaller delay for now, just to see if it works), but my process never runs more than once. What am I doing wrong?
Here is my code:
#WebListener
public class SchedulerService implements ServletContextListener{
#Autowired
UpdateSubscriberService updateSubscriberService;
ScheduledExecutorService scheduledExecService;
public SchedulerService(){
scheduledExecService = Executors.newSingleThreadScheduledExecutor();
}
#Override
public void contextDestroyed(ServletContextEvent arg0) {
scheduledExecService.shutdown();
}
#Override
public void contextInitialized(ServletContextEvent arg0) {
scheduledExecService.scheduleWithFixedDelay(new Runnable(){
#Override
public void run() {
Date date = new Date(System.currentTimeMillis());
System.out.println("Running scheduled update check " + date.toString());
updateSubscriberService.checkForUpdates();
}
}, 60, 30, TimeUnit.SECONDS);
}
}

See this longer Answer of mine on a similar Question.
Wrap run code with try catch
Just a guess: An exception is being thrown. A ScheduledExecutorService halts silently if it encounters an Exception, with no further scheduled work performed.
The run method’s code should always be surrounded by a try-catch to handle and absorb any thrown Exception.
#Override
public void run() {
try { // Let no Exception reach the ScheduledExecutorService.
Date date = new Date(System.currentTimeMillis());
System.out.println("Running scheduled update check " + date.toString());
updateSubscriberService.checkForUpdates();
} catch ( Exception e ) {
System.out.println( "ERROR - unexpected exception" );
}
}
Stub out run method
Take baby steps. Begin with a run method that does nothing but a System.out.println.

Just in case you are ever in a position where the code MUST run once every-so-many-seconds even if the last run hasn't completed yet (which can be very dangerous if not managed properly), you can launch your process inside a different thread inside the timer. Here is sample code.
ScheduledExecutorService scheduledExecService = newSingleThreadScheduledExecutor();
scheduledExecService.scheduleWithFixedDelay(new Runnable()
{
#Override
public void run()
{
// This should be in a try-catch because any error here
// will stop the recurrence
try
{
// The timer will only repeat if the last run is finished. So
// we put each new process in a different thread than the timer
// itself, so the last timer call "finishes" as soon as the process
// leaves the timer's thread.
Thread t = new Thread(new Runnable()
{
public void run()
{
try
{
android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
MyProcessThatShouldRunEverySoManySecondsNoMatterWhat();
}
catch (Exception erTimerThread)
{
Log.e("Error", erTimerThread.toString());
}
}
});
t.setPriority(2);
t.start();
}
catch (Exception erTimer)
{
Log.e("Error", erTimer.toString());
}
}
}, 0, 60, java.util.concurrent.TimeUnit.SECONDS);

Related

Using ScheduledExecutorService, How to Start a Thread without waiting for other thread to complete at fixed interval?

I want to run a task at every particular interval of time regardless of completion of previous thread. And I've used ScheduledExecutorService with the schedule time at every one second. But the problem is, in my Runnable, If I make thread to sleep for 5 seconds, My ScheduledExecuterService also getting executed in every 5 seconds while it supposed to run each thread at 1 second.
It seems like it ScheduledExecuterService is waiting for previous thread to completion. But I want, The task to be triggered at every 1 second no matter what if job inside the task waits for longer time.
Here's is my code.
public class MyTask implements Runnable {
public void run() {
System.out.println("hi there at: "+ new java.util.Date());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
And here's my ScheduledExecutorService Code.
public class JavaScheduledExecutorServiceExample {
public static void main(String[] args) {
ScheduledExecutorService execService = Executors.newScheduledThreadPool(5);
execService.scheduleAtFixedRate(new MyTask(), 0, 1000, TimeUnit.MILLISECONDS);
}
}
Correct me If I'm doing something wrong. And If I'm wrong, is there any alternative to achieve the same? Providing Any best practices could be more helpful :)
"If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute." The behavior you are seeing is consistent with the javadocs
I believe this will perform the way you specified:
public class JavaScheduledExecutorServiceExample {
private static ScheduledExecutorService execService = null;
private static int timesAsleep = 0;
public static class MyTask implements Runnable {
public void run() {
System.out.println("hi there at: "+ new java.util.Date());
// schedule again
execService.schedule(new MyTask(), 1000, TimeUnit.MILLISECONDS);
try {
int i = timesAsleep;
timesAsleep++;
System.out.println("asleep " + i + "----------------------");
Thread.sleep(5000);
System.out.println("awoke " + i + "----------------------");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
execService = Executors.newScheduledThreadPool(5);
execService.schedule(new MyTask(), 1000, TimeUnit.MILLISECONDS);
}
}
Notice the use schedule() instead of scheduleAtFixedRate() on the ScheduledExecutorService instance. It also schedules the next task as soon as it starts the new task.

How do I stop a thread?

I am starting a new thread in my app's onCreate() method like so:
stepsLogger = new Runnable() {
while(!Thread.currentThread().isInterrupted()){
//my code
try {
Thread.currentThread().sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
loggerThread = new Thread(stepsLogger);
loggerThread.start();
While it is not interrupted, it is supposed to do its thing every 10 seconds.
I am logging some text at the start of the Runnable to see how often the code gets run. The first time I run the app it's fine, but every time i restart, the text gets logged more frequently which means that more threads are running.
I have tried to stop them in the onDestroy() method:
#Override
protected void onDestroy() {
super.onDestroy();
loggerThread.interrupt();
loggerThread = null;
}
How do I make sure that the old thread gets stopped whenever the app is restarted?
Thread.interrupt() will wake up a sleeping thread with an InterruptedException, so you're most of the way there already. I'd change your loop in the following way:
while (true) {
// some code
try {
Thread.currentThread().sleep(10000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // restore the thread's interrupted flag
break;
}
}
The bit about re-interrupting the thread is subtle. You can read more about it in this post from one of the primary JVM architects: https://www.ibm.com/developerworks/library/j-jtp05236/
In case this link ever dies, the gist of it is that there can be multiple "recipients" of thread interruption. Catching the exception implicitly clears the thread's interrupted flag, so it's useful to set it again.
You could use a volatile boolean variable to determine when to stop. Something like this:
class WorkerRunnable implements Runnable {
private volatile boolean shouldKeepRunning = true;
public void terminate() {
shouldKeepRunning = false;
}
#Override
public void run() {
while (shouldKeepRunning) {
// Do your stuff
}
}
}
To start it:
WorkerRunnable runnable = new WorkerRunnable();
new Thread(runnable).start();
To stop it:
runnable.terminate();

How one thread can wait until another one finishes to fire some actions

As shown below in the code, I am loading a heavy file on a worker thread fileThread, and while that thread loads the file, I created another thread fileLoadIndicator to show something like the busy indicator on the screen. What I am trying to do now is: after the fileLoadIndicator thread finishes, I want to enable a button, but only after the fileLoadIndicator thread is finished.
My attempts:
loadFile();// the very heavy file
/**
* The below thread "fileLoadIndicator"is to show busy indicator while our main file
that takes approx. 8 seconds to be loaded
*
*/
fileLoadIndicator = new Thread(fileLoadIndicatorRun);
fileLoadIndicator.start();
indicatorMonitor = new Thread(indicatorMonitorRun);
indicatorMonitor.start();
...
...
Runnable fileLoadIndicatorRun = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
statusarea.append(Log.w(TAG, "busyIndicatorRunnable", "Loading."));
StringBuilder sb = new StringBuilder(".");
do {
try {
fileThread.join(1500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sb.append(".");
statusarea.append(sb.toString());
} while (fileThread.getState() != State.TERMINATED);
//statusarea.append("/n");
}
};
Runnable indicatorMonitorRun = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
fileLoadIndicator.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setViewEnableState(Bpause, true);
}
};
But what happens in the indicatorMonitorRun is, the indicatorMonitor thread waits until the whole method loadFile(), which process the heavy file line by line and the whole process might takes 70 minutes, finishes. I just want to enable a button, only when the fileLoadIndicator thread finishes, and I should not wait until the whole file is loaded and processed which a very long time.
Kindly please let me know how can I do so.
I would suggest using ExecutorService to manage your thread pools and if you're using Java 8, take advantage of CompletableFuture as it simplifies these types of tasks without requiring complex thread wait/notify and java.util.concurrency types, for example:
package so.thread.wait;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class LongThreadWait {
public static void main(String[] args) throws Exception {
// thread pool for long running loaders
final ExecutorService fileLoaders = Executors.newCachedThreadPool();
// hook to be invoked when the file is done loading
final CompletableFuture<Long> completionFuture = new CompletableFuture<>();
completionFuture.thenAcceptAsync(LongThreadWait::completionConsumer);
fileLoaders.submit(new FileLoader(completionFuture));
Thread.sleep(TimeUnit.SECONDS.toMillis(3));
}
private static void completionConsumer(Long millis) {
System.out.println("Completed on Thread [" + Thread.currentThread().getName() + "] in " + millis + " ms");
}
private static class FileLoader implements Runnable {
private CompletableFuture<Long> completionFuture;
public FileLoader(CompletableFuture<Long> completionFuture) {
this.completionFuture = completionFuture;
}
#Override
public void run() {
long start = System.currentTimeMillis();
// load file for a long time
System.out.println("Loading file on Thread [" + Thread.currentThread().getName() + "]");
try {
Thread.sleep(TimeUnit.SECONDS.toMillis(2));
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
// invoke the completion future with the elapsed milliseconds
completionFuture.complete(end - start);
}
}
}
The CompletableFuture.thenAcceptAsync(..) by default runs the supplied hook in the default "ForkJoin" thread pool in the JVM, there is an optional second argument where you can supply your own ExecutorService to define what thread the completion hook is executed on.
This type of setup simplifies thread management and complex wait semantics.
You should also note that CompletableFuture has a comprehensive fluent API to make complex chaining of thread results simpler.
Consider using a CountDownLatch. Initialize this to 1. When your loading thread is done, it can call countDown. Your monitor thread can either poll count or simply await completion.
You could used a "ExecutorService" to create a thread pool, then monitor the threads and wait for the threads to terminate to enable the button.
class FileThreadThread implements Runnable {
public FileThreadThread() {
}
#Override
public void run() {
}
}
class FileLoadIndicatorRunThread implements Runnable {
private ExecutorService fileLoadIndicatorExecutor = null;
#Override
public void run() {
if (fileLoadIndicatorExecutor == null || fileLoadIndicatorExecutor.isShutdown()) {
fileLoadIndicatorExecutor = Executors.newCachedThreadPool(CustomizableThreadFactory.createSingleNamedFactory("FileLoaderThreadPool"));
}
for(int i=0; number_of_files; i++){
fileLoadIndicatorExecutor.execute(new FileThreadThread());
}
//Request executor shutdown after all threads are completed
fileLoadIndicatorExecutor.shutdown();
while (isRunning) {
boolean threadTerminated = fileLoadIndicatorExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
if(threadTerminated){
// enable a button
isRunning = false;
}
}
}
}

How to return from JUnit test to main method if part of test takes too long

I try to run junit from my main() method:
public static void main(String... args) throws ClassNotFoundException,
IOException {
//...
logger.debug("className " + className + "methodName " + methodName);
Request request = Request.method(Class.forName(className), methodName);
return new JUnitCore().run(request);
}
I have an E2E test with 10 commands (say). It is run by JUnit and I want to limit the run time of commands 3-5 to X millis (where X is determined at run time). If it runs longer than X I want to return to the main() and print something.
I have tried System.exit() but it closes the whole application. I tried:
public void setTimeOut(String criticalBlockTimeOutMilli) {
if (criticalBlockTimeOutMilli != null) {
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
E2eResult e2eResult = E2eResult.getInstance();
e2eResult.status = E2eStatus.TIMEOUT;
//System.exit(2);
}
};
new Timer().schedule(timerTask, Long.parseLong(criticalBlockTimeOutMilli));
}
}
public void setTimeOut(final Thread thread, String criticalBlockTimeOutMilli) {
if (criticalBlockTimeOutMilli != null) {
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
E2eResult e2eResult = E2eResult.getInstance();
e2eResult.status = E2eStatus.TIMEOUT;
thread.interrupt();
}
};
new Timer().schedule(timerTask, Long.parseLong(criticalBlockTimeOutMilli));
}
}
but the main thread continues to run the test even if exceeds the limit. What would you suggest?
Unit testing might not be the best approach to solving this sort of performance testing. However, if there's some reason this must be done, read on...
Use an ExecutorService to run the commands you want, with a given timeout. If the timeout expires, throw your own exception that you can catch in your main thread:
#Test
public void yourTest() throws Exception {
// Do commands 1-2
ExecutorService service = Executors.newSingleThreadExecutor();
Future<Void> result = service.submit(new Callable<Void>() {
#Override
public Void call() throws Exception {
// call commands 3-5
return null;
}
});
try {
result.get(42, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
throw new YourOwnException();
}
service.shutdown();
// Do commands 6-10
}
One fairly simple mechanism is to use a BlockingQueue to indicate that the test completed. If you find it didn't you can then interrupt it. This will only work if the test correctly responds to being interrupted.
// Send FINISHED down this queue when test completes.
final BlockingQueue<Object> finished = new ArrayBlockingQueue<>(1);
// FINISHED cookie.
static final Object FINISHED = new Object();
public void test() throws InterruptedException {
Thread test = new Thread(new Runnable() {
#Override
public void run() {
// Do your stuff.
// ...
// Signal we finished.
finished.add(FINISHED);
}
});
// Start the test in it's own thread.
test.start();
try {
// Wait for your time.
if (FINISHED == finished.poll(5, TimeUnit.MILLISECONDS)) {
// It completed! No problems.
} else {
// It hasn't finished! Interrupt it.
test.interrupt();
};
} catch (InterruptedException ex) {
// We were interrupted! Do something.
test.interrupt();
// Rethrow it.
throw(ex);
}
}
You can extend this mechanism by adding a "Started" message too so you can ensure that the test thread gets at least a chance to run.

How to stop a thread as soon as a certain amount of time expires? [duplicate]

This question already has answers here:
How to properly stop the Thread in Java?
(9 answers)
Closed 9 years ago.
I am having a problem trying to stop a thread instantly after a certain amount of time has elapsed, because thread.stop and similar others have been depreciated.
The thread that I am trying to stop uses my mouse and I need to stop it so that I can use my mouse in other ways.
What I was thinking is the code below, which was just to make another thread to watch how long the main thread has been running and if it is alive, stop it, but I can't accomplish this.
public void threadRun(int a) {
Thread mainThread = new Thread(new Runnable() {
#Override
public void run() {
// does things with mouse which may need to be ended while they
// are in action
}
});
Thread watchThread = new Thread(new Runnable() {
#Override
public void run() {
if (timeFromMark(mark) > a) {
if (mainThread.isAlive()) {
// How can I stop the mainThread?
}
}
}
});
}
You need to define a class for your second thread that extends runnable and pass the first thread as an argument.
Then you can stop the first thread.
But instead of doing this manually, have a look at the Java ThreadPoolExecuter and its awaitTermination(long timeout, TimeUnit unit) method. (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html )
Will save a lot of work.
ExecutorService executor = Executors.newFixedThreadPool(1);
Runnable r = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
System.out.println("doing stuff");
Thread.sleep(10000);
System.out.println("finished");
} catch (InterruptedException e) {
System.out.println("Interrupted before finished!");
}
}
};
executor.execute(r);
executor.shutdown();
try {
executor.awaitTermination(1, TimeUnit.SECONDS);
executor.shutdownNow();
} catch (InterruptedException e) {
//
}
System.out.println("Thread worker forced down. Continue with Application...");
Produces:
doing stuff
Interrupted before finished!
Thread worker forced down. Continue with Application...
Last two messages are nearly equal in terms of time and may change positions (its two different threads, continuing)
Java has deprecated methods for explicitly killing another thread (like Thread.stop / Thread.destroy). The right way is to make sure the operations on the other thread can handle being told to stop (for example, they expect an InterruptedException, which means you can call Thread.interrupt() in order to stop it).
Taken from How do I kill a thread from another thread in Java?
Killing/stopping threads is a bad idea. That's why they deprecated those methods. It's better to ask the thread to stop. E.g., something like the example below. (But note: if "do_something()" takes a long time, then you might want to use an interrupt to abort whatever it is.)
import java.util.concurrent.atomic.AtomicBoolean;
public class Stoppable {
private AtomicBoolean timeToDie = new AtomicBoolean(false);
private Thread thread;
public void start() {
if (thread != null) {
throw new IllegalStateException("already running");
}
thread = new Thread(new Runnable() {
public void run() {
while (!timeToDie.get()) {
// do_something();
}
}
});
thread.start();
}
public void stop() throws InterruptedException {
timeToDie.set(true);
thread.join();
thread = null;
}
}

Categories