How to cancel incomplete task on ExecutorService [duplicate] - java

This question already has answers here:
Java ExecutorService pause/resume a specific thread
(3 answers)
Closed 5 years ago.
I have submitted two tasks, task1 & task2 to the ExecutorService. Task2 needs 5 seconds to complete, and task1 need 10 seconds.
How can I stop the task(s) submitted (ie: task1) when task2 completes and continues the rest of logic?
Here's my code so far:
public class mt_poc {
public static void action_1 () throws InterruptedException {
System.out.println("action_1 invoke " );
Thread.sleep(10000);
action_2 ();
System.out.println("action_1 done" );
}
public static void action_2() throws InterruptedException {
System.out.println("action_2 invoke " );
Thread.sleep(5000);
System.out.println("action_2 done " );
}
public static void main(String[] args) {
System.out.println("TEST");
Runnable task1 = new Runnable() {
public void run() {
try {
action_1 ();
}
catch(InterruptedException e) {
System.out.println("action_1 invoke interrupted");
}
System.out.println("action_1 invoke run is over" );
}
};
Runnable task2 = new Runnable() {
public void run() {
try {
action_2 ();
}
catch(InterruptedException e) {
System.out.println("action_2 invoke interrupted");
}
System.out.println("action_2 invoke run is over" );
}
};
ExecutorService executor = Executors.newFixedThreadPool(2);
try {
executor.submit(task1);
executor.submit(task2);
// cancel uncomplete task
executor.shutdown();
executor.awaitTermination(5, TimeUnit.SECONDS);
// continues the rest of logic
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Shutdown executor");
}
}

you can use shutdownNow() method
Attempts to stop all actively executing tasks, halts the processing of
waiting tasks, and returns a list of the tasks that were awaiting
execution.
for full documentation:
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html
shutdown() method will wait for all the threads to finish before closing the executor

You have to retrieve the Future objects from the submit function.
These are used to control the running thread and get the status of it.
If you have the futures, call Future2.get(). This will block the thread until the Task2 is finished. No you can use Future1.cancel(true) to abort the other thread.
But pausing and resuming is not possible. See Java ExecutorService pause/resume a specific thread
If you want such specific behaviour you need to use Threads.
But why you want to do this in seperate Threads as it would be much simpler and efficient t use a single one.

Related

How to completely stop / terminate a task that has already been submitted to an ExecutorService in Java?

Problem : I have an use case where I want to cancel a task that has already been submitted to an executor service. future.cancel() is not helpful to me as the task does not go to wait() / sleep() state during the execution. Also, adding isInterrupted() is not scalable because of the following reasons,
Many other services are called during the execution and using isInterrupted() before each call is ugly.
If suppose one of the service calls in one of the submitted tasks takes more than X milliseconds, I would want to abort the task and free up the tread.
Here is a sample code on how I am using future.cancel() right now. Is there a way where I can completely abort the submitted task / kill the thread executing the task in the main() function without disturbing the other submitted tasks.
public class Main {
ExecutorService executorService = newFixedThreadPool(10);
public static void main(String[] args) {
Future<Integer> test = new Main().sample();
try {
test.get(0, java.util.concurrent.TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
System.out.println("Throwing InterruptedException");
} catch (java.util.concurrent.ExecutionException e) {
System.out.println("Throwing ExecutionException");
} catch (java.util.concurrent.TimeoutException e) {
System.out.println("Throwing TimeoutException");
} finally {
System.out.println(test.cancel(true));
}
System.out.println("main() COMPLETED");
}
private Future<Integer> sample() {
return executorService.submit(() -> {
System.out.println("sample() STARTED");
anotherSample();
System.out.println("sample() COMPLETED");
return 1;
});
}
private void anotherSample() throws Exception {
System.out.println("anotherSample() STARTED");
for (int i = 0; i < 100000; i++) {
// do nothing
}
System.out.println("anotherSample() COMPLETED");
}
}
Output :
Throwing TimeoutException
sample() STARTED
anotherSample() STARTED
true
main() COMPLETED
anotherSample() COMPLETED
sample() COMPLETED

ExecutorService JVM doesn't terminate [duplicate]

This question already has answers here:
Java ServiceExecutor terminating condition
(4 answers)
Closed 7 years ago.
I don't understand why I have to call executorService.shutdown()
explicitly to terminate executorService.
If I will not call shutdown() then the JVM will not terminate on its own.
What is wrong with my program or what concept I am lacking?
public class ExecutorServiceExample {
public static class Task1 implements Runnable {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Message from Task1 :"
+ Thread.currentThread().getName());
}
}
public static class Task2 implements Runnable {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Message from Task2 :"
+ Thread.currentThread().getName());
}
}
public static class Task3 implements Runnable {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Message from Task3 :"
+ Thread.currentThread().getName());
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
Future future1 = executorService.submit(new Task1());
Future future2 = executorService.submit(new Task2());
Future future3 = executorService.submit(new Task3());
}
}
Output:
Message from Task2 :pool-1-thread-2
Message from Task1 :pool-1-thread-1
Message from Task3 :pool-1-thread-3
JVM is still alive. If I will call shutdown() then only JVM would die.
According to Thread javadoc:
The Java Virtual Machine continues to execute threads until either of the following occurs:
The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.
Your executor creates non-daemon threads which prevent your JVM from shutting down. Threads created by executors are usually pooled to run more than one task submitted to the executor - often this is a performance optimisation to reuse threads so they run more then one task (as creating new thread is an expensive operation). Depending on the implementation and configuration of the executor (e.g. see ThreadPoolExecutor doc, especially keepalive configuration) it might keep the threads running forever or terminate when they are unused for some time.
You must either call shutdown on your executor or create it with a custom ThreadFactory (e.g. using Executors.newFixedThreadPool(int, ThreadFactory)) where that thread factory will configure new threads as daemon ones.

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;
}
}

How do I respawn threads if they die

I have multiple threads of multiple types (Different classes). I want in case one of them throws an exception and dies to be replaced by another NEW thread. I am aware of the join thread function but how would I go about implementing them for 5 different type of threads such as in case type 1 thread dies is instantly replaced without having to wait for type 2 to die first.
This is some sample pseudo-code.
class1 implements runnable{
void run(){
try{
while(true){
repeat task
}
} catch(Exception e){
log error
}
}
}
class2 implements runnable{
void run(){
try{
while(true){
repeat task
}
} catch(Exception e){
log error
}
}
}
class3 implements runnable{
void run(){
try{
while(true){
repeat task
}
} catch(Exception e){
log error
}
}
}
public main(){
// start all threads .start()
}
I want in case one of them throws an exception and dies to be replaced by another NEW thread.
I don't quite understand why you can't do:
public void run() {
// only quit the loop if the thread is interrupted
while (!Thread.currentThread().isInterrupted()) {
try {
// do some stuff that might throw
repeat task;
} catch (Exception e) {
// recover from the throw here but then continue running
}
}
}
Why do you need to restart a NEW thread? Just because a task threw an exception doesn't mean that it is somehow corrupt and it needs a fresh one to work appropriately. If you are trying to catch all exceptions (including RuntimeException) then catch (Exception e) will do this. If you want to be really careful you can even catch Throwable in case there is a chance that Errors are being generated – this is relatively rare.
If you actually have multiple tasks (or really anytime you are dealing with threads), you should consider using the ExecutorService classes. See the Java tutorial.
// create a thread pool with 10 workers
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// or you can create an open-ended thread pool
// ExecutorService threadPool = Executors.newCachedThreadPool();
// define your jobs somehow
threadPool.submit(new Class1());
threadPool.submit(new Class2());
...
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
So instead of forking a thread to do multiple tasks, you start a thread pool and it starts threads as necessary to accomplish a bunch of tasks. If a task fails, you could certain submit another task to the pool although that's a slightly strange pattern.
If you want to wait for all of the tasks to finish you'd use:
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
boolean shouldStop() {
// it's a good idea to think about how/when to stop ;)
return false;
}
void runThreadGivenType(final Runnable taskToRun) {
new Thread() {
#Override
public void run() {
try {
taskToRun.run();
} finally {
if (!shouldStop()) {
runThreadGivenType(taskToRun);
}
}
}
}.start();
}
public void main(String[] args) throws Exception {
runThreadGivenType(new Runnable() { public void run() { System.out.println("I'm almost immortal thread!"); throw new RuntimeException(); } });
TimeUnit.SECONDS.sleep(10);
}
and it's a good idea to think about executors to manage thread pools too. plain, [un/hand]-managed threads are not the best practice ;)

Some complex Threading concept [duplicate]

This question already has answers here:
Run Java Threads sequentially
(13 answers)
Closed 9 years ago.
how to Execute threads sequentially ? (e.g i have 3 threads T1,T2,T3 and i want to start these threads same time but ensure that they should run sequentially one after other like first T1 then T2 and at last T3.)
Thread t1= new Thread(new Runnable()
{
void run()
{System.out.println("inside Thread1");}
});
Thread t2= new Thread(new Runnable()
{
void run()
{System.out.println("inside Thread2");}
});
Thread t3= new Thread(new Runnable()
{
void run()
{System.out.println("inside Thread3");}
});
t1.start();
t2.strat();
t3.start();
output:
inside Thread1
inside Thread2
inside Thread3
each time u run o/p should be as shown above.
In my humble opinion, you perhaps do not need threads, just call T1(), T2(), T3() methods sequentially in your code?
Threads are used to run multiple tasks in parallel.
You can synchronize these threads through flag/s. You can also use inbuilt synchronizers provided by Java like BlockingQueue.
Use BlockingQueues to synchronize the threads
final BlockingQueue q1 = new SynchronousQueue();
final BlockingQueue q2 = new SynchronousQueue();
Thread t1 = new Thread() {
public void run() {
...
try {
q1.put(new Object());
} catch (InterruptedException e) {
}
};
};
Thread t2 = new Thread() {
public void run() {
try {
q1.take();
...
q2.put(new Object());
} catch (InterruptedException e) {
}
}
};
Thread t3 = new Thread() {
public void run() {
try {
q2.take();
...
} catch (InterruptedException e) {
}
}
};
t1.start();
t2.start();
t3.start();
Threads are used to run multiple tasks at a same time.
In your case you need different methods called sequentially rather than Threads.
You should use:
class Methods_Than_Threads{
void T1()
{
//something
}
void T2()
{
//something
}
void T3()
{
//something
}
public static void main(String []args)
{
T1();//First T1
T2();//Second T2
T3();//Third T3
}
}
You should separate the actual tasks from how they are executed. I.e. don't extend Thread and overwrite run, instead implement Runnable as the task and don't care about the way it is executed.
That way you can design (+change later) the way you execute tasks independently from the actual implementation of a task.
E.g. Call each .run() directly if you want to execute them after each other or let some Executor handle them or even run them via new Thread manually.
If they have to wait on each other you could also use a Future. For example:
class ProcessingChainElement implements Callable<String> {
private final Future<String> previous;
public ProcessingChainElement(Future<String> previousResult) {
previous = previousResult;
}
#Override
public String call() throws Exception {
// prepare something that may take some time but does not depend on
// any previous result
Thread.sleep(500);
// get result from previous task, this blocks until it is available
result = previous.get() + " [" + System.currentTimeMillis() + "]";
return result;
}
}
And build a chain of tasks that can be executed in any way you want.
ExecutorService executor = Executors.newFixedThreadPool(3);
Future<String> result1 = executor.submit(...
Future<String> result2 = executor.submit(new ProcessingChainElement(result1));
...
Result is that each task can wait on results of a previous task but may very well run in parallel if there is anything that can be run in parallel.
Example http://ideone.com/VAg8q3 demonstrates that 3 tasks that take >= 500ms each and depend on each other could be done much quicker than actually running them in sequence.

Categories