Stop a runnable in a separate Thread - java

Hey there i currently have a problem with my android app. I´m starting an extra thread via
implementing the Excecutor Interface:
class Flasher implements Executor {
Thread t;
public void execute(Runnable r) {
t = new Thread(r){
};
t.start();
}
}
I start my Runnable like this:
flasherThread.execute(flashRunnable);
but how can i stop it?

Ok, this is just the very basic threading 101, but let there be another example:
Old-school threading:
class MyTask implements Runnable {
public volatile boolean doTerminate;
public void run() {
while ( ! doTerminate ) {
// do some work, like:
on();
Thread.sleep(1000);
off();
Thread.sleep(1000);
}
}
}
then
MyTask task = new MyTask();
Thread thread = new Thread( task );
thread.start();
// let task run for a while...
task.doTerminate = true;
// wait for task/thread to terminate:
thread.join();
// task and thread finished executing
Edit:
Just stumbled upon this very informative Article about how to stop threads.

Not sure that implementing Executor is a good idea. I would rather use one of the executors Java provides. They allow you to control your Runnable instance via Future interface:
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<?> future = executorService.submit(flashRunnable);
...
future.cancel(true);
Also make sure you free resources that ExecutorService is consuming by calling executorService.shutdown() when your program does not need asynchronous execution anymore.

Instead of implementing your own Executor, you should look at ExecutorService. ExecutorService has a shutdown method which:
Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.

I would suggest to use the ExecutorService, along with the Furure object, which gives you control over the thread that is being created by the executor. Like the following example
ExecutorService executor = Executors.newSingleThreadExecutor();
Future future = executor.submit(runnabale);
try {
future.get(2, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
Log.warn("Time out expired");
} finally {
if(!future.isDone()&&(!future.isCancelled()))
future.cancel(true);
executor.shutdownNow();
}
This code says that the runnable will be forced to terminate after 2 seconds. Of course, you can handle your Future ojbect as you wish and terminate it according to your requierements

Related

Java add shutdown hook inside method

In my code I'm using CompletionService and ExecutorService in order to start a bunch of Thread to execute some task (that can take a lot of time).
So I have a method that creates the ExecutorService and the CompletionService, then starts submitting threads and then take the results.
I would like to add a shutdown hook in order to gracefully shutdown the executor (I know that probably I should handle releasing resources instead of executor shutdown but in my case each thread has its own resources so shutting down them gracefully can be a good soulution I suppose).
For this reason I write the following code
public Class myClass{
...
private CompletionService<ClusterJobs> completion;
final long SHUTDOWN_TIME = TimeUnit.SECONDS.toSeconds(10);
...
public Message executeCommand(Message request){
final ExecutorService executor = Executors.newFixedThreadPool(30);
completion = new ExecutorCompletionService<ClusterJobs>(executor);
....//submit and take results
Runtime.getRuntime().addShutdownHook(new Thread(){
#Override
public void run() {
logger.debug("Shutting down executor");
try {
if (!executor.awaitTermination(SHUTDOWN_TIME, TimeUnit.SECONDS)) {
logger.debug("Executor still not terminate after waiting time...");
List<Runnable> notExecuted= executor.shutdownNow();
logger.debug("List of dropped task has size " + droppedTasks.size());
}
}catch(InterruptedException e){
logger.error("",e);
}
}
});
}
}
Do you think that this is a reasonable solution or it's unsafe to register and unregister shutdown hook using local classes?
Thanks in advance
Regards
From Design of the Shutdown Hooks API:
Simple shutdown hooks can often be written as anonymous inner classes, as in this example:
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() { database.close(); }
});
This idiom is fine as long as you'll never need to cancel the hook, in which case you'd need to save a reference to the hook when you create it.

Stop a Runnable in a Thread imediatly

I try to implement a version of software transactional memory library in java with some sort of scheduler which holds some Thread objects. I want to implement a mechanism where the scheduler tells the Thread to immediatly stop execution, drop its Runnable, create a new one and rerun it. This is really half cooked so far but what I don't want is to recreate the hole Thread because it will work as a state holder for several Variables (deepcopies of other variables only the Thread has - copy tasks are a choke here so the Thread should not be fully recreated)
My problem is that I don't know about anything that terminates a method while it executes and frees all the resources (If the scheduler tells the thread to restart everything the Runnable did is invalid and must be redone) and start the run method again with fresh input variables.
The goal is to avoid unecesarry executions and there should be no variable in the runnable which asks if it was interreupted to then skip the execution or something. Just stop the execution and kill it from something the runnable itself is not aware off. I hope it's clear what I want if not please ask for the unclear points help would be very appreciated :)
A simple Tutorial to cancel the Runnable and start it again.
public class RestartThreadTutorial {
public static void main(String args[]){
ExecutorService executorService = Executors.newFixedThreadPool(5);
Future<?> taskHandler = executorService.submit(new Task());
//restart the task after 3 seconds.
try{
Thread.sleep(3000);
}catch(InterruptedException e){
//empty
}
taskHandler.cancel(true); //it will cancel the running thread
if (taskHandler.isCancelled()==true){//check the thread is cancelled
executorService.submit(new Task());//then create new thread..
}
}
public static class Task implements Runnable{
private int secondsCounter;
#Override
public void run(){
while(true){
System.out.println("Thread -"+Thread.currentThread().getName()+"elapsed - "+ (secondsCounter++) +"second");
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
break;
}
}
}
}
}

Using Executor & Runnable together to kill threads after some time

I happened to come across this article for killing a thread after some time using the Executor service : Killing thread after some specified time limit in Java
This is the code mentioned in the article :
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new Task()), 10, TimeUnit.MINUTES); // Timeout of 10 minutes.
executor.shutdown();
Now that I have a runnable thread to be executed in my program .How do I kill this thread after some time using the above mentioned code?
Here's a part of my code which I have used for creating threads :
public static List<Thread> thread_starter(List<Thread> threads,String filename)
{ String text=read_from_temp(filename);
Runnable task = new MyRunnable(text);
Thread worker = new Thread(task);
worker.start();
// Remember the thread for later usage
threads.add(worker);
return threads;
}
public class MyRunnable implements Runnable {
MyRunnable(String text)
{
this.text=text;
}
#Override
public void run() {
/* other computation*/
}
I create multiple threads by calling thread_started() function .
Can anyone please help me on combining Executor Service with it . I tried a lot but couldn't find any way out !
In java, you can NOT kill a running thread directly. If you want to kill your running thread, you need a running flag in your task, check it in thread task, and set it outside. Eg:
MyRunnable task = ....;
......
task.running = false; //stop one task
public class MyRunnable implements Runnable {
public boolean running = true;
public void run() {
while(running){
.....
}
}
What you mentioned 'ExecutorService' is single thread 'ExecutorService', it would exec tasks one by one, what it do for timeout is just waiting a task completed and calculate/compare each task's time with timeout. You can find it in java's source code 'AbstractExecutorService.java'.

ExecutorService, how to know when all threads finished without blocking the main thread?

I have a multithreaded implementation where i create an ExecutorService and submit tasks to be executed, i want to know when all the threads is submited have finished without blocking the main thread and the UI. I've tried ExecutorService.awaitTermination() but it blocks the main thread and the UI. I've searched alot but i can't seem to find an elegant way of doing this. I'm currently thinking about creating another thread that counts the amount of threads finished and launches an event when they all finished, but that doesn't to be a good approach and i wanted a better solution!
Use a SwingWorker to shutdown the thread pool and call awaitTermination(). This will prevent the UI from blocking and call done() from the Event Dispatch Thread on your SwingWorker implementation which you can use to trigger the whatever UI changes you need.
If you desire to keep track of the threads running via a UI update you can use the the worker thread to monitor this in a loop and call publish() with arguments which then get passed to your implementation of process() on the EDT.
Why not use a CountDownLatch and then notify the main thread when the latch has been completed.
isTerminated() will do
note however that both awaitTermination and isTerminated will only give you a meaningful result after you have called shutdown
You can maintain a separate thread to track when the executor service instance shuts down:
final ExecutorService execSvc = ...;
execSvc.submit(task1);
...
execSvc.submit(taskN);
// important to request the exec service to shut down :)
execSvc.shutdown();
new Thread(new Runnable() {
public void run() {
while (!execSvc.isTerminated()) {
try {
execSvc.awaitTermination(60, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// ignore exception
}
}
System.out.println("ExecSvc.run: exec service has terminated!");
// possibly submit a task using SwingUtilities.invokeLater() to update the UI
}
}).start();
Using CountDownLatch
CountDownLatch latch = new CountDownLatch(totalNumberOfTasks);
ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
while(...) {
taskExecutor.execute(new MyTask());
}
try {
latch.await();
} catch (InterruptedException E) {
// handle
}
and within your task (enclose in try / finally)
latch.countDown();
Or on ExecutorService you call shutdown() and then awaitTermination()
ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
while(...) {
taskExecutor.execute(new MyTask());
}
taskExecutor.shutdown();
try {
taskExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
...
}
Also have a look at THIS answer

Interrupt a sleeping thread

Trying to interrupt a running thread, in this example, t1, which is executed by a thread in a thread pool.
t2 is the one that sends the interrupt.
I'm unable to stop the running t1, t1 does not get InterruptedException.
What am I missing?
Executor exec1 = Executors.newFixedThreadPool(1);
// task to be interrupted
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
System.out.println("starting uninterruptible task 1");
Thread.sleep(4000);
System.out.println("stopping uninterruptible task 1");
} catch (InterruptedException e) {
assertFalse("This line should never be reached.", true);
e.printStackTrace();
}
}
};
final Thread t1 = new Thread(runnable);
// task to send interrupt
Runnable runnable2 = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
t1.interrupt();
System.out.println("task 2 - Trying to stop task 1");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t2 = new Thread(runnable2);
exec1.execute(t1);
t2.start();
t2.join();
Seems like you misunderstand threads and Executors. You create two threads object for two runnables, but start only one of them (t2), t1 you pass to Executor to run inside it. But executor does not need Thread to be supplied -- it just need Runnable implementation. Executor itself is a thread pool (usually, but it's not required), and it just creates (and pool) threads inside it. It sees you thread just as simple Runnable (which is Thread implements). So you actualy send interrupt to the thread which was never started.
If you really want to make your code works, you should remove Executor, and just start both threads explicitly.
Your mistake is that you're trying to execute a Thread on a ThreadPool.
This appears to work, because Thread happens to implement Runnable, but because the thread is only being used as a Runnable and is not started as a Thread, calling methods like #interrupt() won't have the desired effect.
If you still need to use a thread pool, you should instead look into using a class like FutureTask. Wrap your Runnable in a FutureTask, and then submit the task to a thread pool. Then, when you want to interrupt the task, call futureTask.cancel(true).
The problem is that you can never really know which thread would be used by the Executor to run your task.
Even though you have submitted a Thread object, The Executor will use the thread created by the fixed thread pool. Thus the thread with reference t1 is not the thread in which your task is going to be executed. so calling t1.interrupt() is not going to do anything.
To properly way to do this is to use an ExecutorService and use the submit() to submit a Runnable/Callable object. This will return a Future which exposes a cancel() method which can be used to cancel the task.
Calling Thread.interrupt does not necessarily throw an InterruptedException. It may just set the interrupted state of the thread, which can be polled by Thread.interrupted() or Thread.isInterrupted.
See http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html#interrupt() for more details.
To interrupt the executor thread ,
final ExecutorService exec1 = Executors.newFixedThreadPool(1);
final Future<?> f = exec1.submit(runnable);
...
f.cancel(true);

Categories

Resources