Utility of Future.cancel(boolean) method - java

I was simply exploring the java.util.concurrent package.
I learnt that the class 'Future' has a method boolean cancel(boolean mayInterruptIfRunning)
Please find attached the test code I wrote :
package com.java.util.concurrent;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
public class FutureTester {
/**
* #param args
* #throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
int poolCnt = 1;
Callable<NumberPrinter> numberPrinter = null;
ScheduledThreadPoolExecutor schPool = new ScheduledThreadPoolExecutor(
poolCnt);
ScheduledFuture<NumberPrinter>[] numPrinterFutures = new ScheduledFuture[poolCnt];
FutureTask<NumberPrinter>[] futureTask = new FutureTask[poolCnt];
for (int i = 0; i < poolCnt; i++) {
numberPrinter = new NumberPrinter();
futureTask[i] = new FutureTask<NumberPrinter>(numberPrinter);
/*
* numPrinterFutures[i] = (ScheduledFuture<NumberPrinter>) schPool
* .schedule(futureTask[i], 0, TimeUnit.MILLISECONDS);
*/
numPrinterFutures[i] = (ScheduledFuture<NumberPrinter>) schPool
.submit(futureTask[i]);
}
//Thread.sleep(30);
if (numPrinterFutures.length > 0) {
System.out.println("Task completed ? "
+ numPrinterFutures[0].isDone());
System.out.println("Task cancelled ? "
+ numPrinterFutures[0].cancel(true));
System.out.println("Is task cancelled ? "
+ numPrinterFutures[0].isCancelled());
}
}
}
class NumberPrinter implements Callable<NumberPrinter> {
private int counter = 10;
#Override
public NumberPrinter call() throws Exception {
// TODO Auto-generated method stub
while (counter > 0) {
if (Thread.interrupted()) {/*OUCH !!!*/
return null;
}
System.out.println("counter = " + (counter--));
}
return this;
}
}
Intially,I assumed that cancelling a task will also stop the execution of a running thread(the 'OUCH' part NOT included).But I got the output as follows :
counter = 10
Task completed ? false
counter = 9
Task cancelled ? true
counter = 8
Is task cancelled ? true
counter = 7
counter = 6
counter = 5
counter = 4
counter = 3
counter = 2
counter = 1
On further reading on stackoverflow itself,it was said that
The 'cancel' method can only stop the 'unstarted' jobs(which contradicts with the api description of the method)
The cancel method simply interrupts the running thread which then
must return from the run() method
Hence,I included the 'OUCH' part - a while loop checking for interruption;the output was as follows :
Task completed ? false
counter = 10
Task cancelled ? true
Is task cancelled ? true
QUESTION :
If one is supposed to write something analogous to the 'OUCH' part to stop the running thread,what is the utility/value of the cancel method. How does wrapping a Callable in a FutureTask help if the Thread can't be stopped by cancel? What is the design/conceptual/logical part that I am overlooking?

How does wrapping a Callable in a FutureTask help if the Thread can't be stopped by cancel?
You want to cancel the task, not the thread running it. Using cancel(true) prevents the task from starting (but doesn't remove it from the queue) and interrupts the thread if the task has started. The Task can ignore the interrupt, but there is no clean way of killing a thread without killing the whole process.

The problem that you are overlooking is that only cooperating threads can be stopped safely in Java.
Indeed, if you look at the Thread API, you will notice that there are some methods called destroy, pause, stop, and resume that were deprecated in Java 1.1. The reason that they were deprecated is that the Java designers realized that they generally can't be used safely. The reasons are explained in the note "Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?".
The problem is inherent in the Java threading model, and could only be avoided by curtailing the ability of one thread to interact with objects used by other threads. There is a JSR that specifies one one way of doing this ... Isolates ... but no mainstream JVMs implement these APIs to my knowledge.
So bringing this back to your question, the usefulness of Future.cancel is that it solves the subset of the problem that can be solved in the context of futures.

Invoking cancel(true) will prevent the Future from executing if not already run and will be interrupted if currently running. At this point, the burden to cancel the Future is put on the developer.
Since it is a thread pool it wouldn't make sense to stop the thread (though it rarely if ever makes sense to stop a thread). The cancel/interrupt will not cause the thread to exit from its run method. After the execution of your Callable's call method it will simply pull the next item off the work queue and process that.
The utility of the cancel method is simply to signal the executing thread that some process want's that Callable to stop - not the thread - so you will have to handle the stopping of the Callable yourself.

Suppose, that the code that runs as part of your future does not support cooperative cancellation or interruption. Then cancelling an unstarted task is the best thing you can possibly do. That is why this method exists.
In general I think of cancellation as strictly cooperative. Just cancelling some piece of code by force can lead to corrupted state.

Related

ThreadPool getActiveCount() vs getPoolSize()

Although this topic has been discussed broadly in other posts I want to present my use case and clarify .So apologies if I am wasting anyone's time. I have the following runnable implementation. Basically infinitely running thread unless java.lang.Error gets thrown by the business logic.
public void run (){
while(true){
try{
//business logic
}catch(Exception ex){
}
}
}
I have about 30 of the above threads started from ExecutorService.
private final ExecutorService normalPriorityExecutorService = Executors.newFixedThreadPool(30);
for(int i=0;i<30;i++) {
normalPriorityExecutorService.submit(//Above Runnable);
}
I want to check and kill the JVM process if the thread count becomes zero on this Executor Service.
if (normalPriorityExecutorService instanceof ThreadPoolExecutor && ((ThreadPoolExecutor) normalPriorityExecutorService).getActiveCount() ==0) {
log.error("No Normal Priority response listeners available. Shutting down App!");
System.exit(1);
}
From my reading since these runnable threads are infinitely running under normal circumstances I will have 30 of them active unless they get killed by runtime Errors.
Question is using getActiveCount() the right approach for my use case ? By the way, when I tried using getPoolSize() instead of getActiveCount(), I did not get the right behavior while testing (I forcefully threw an error to kill a specific thread) and the poolSize still remained thirty.
Since you never use the thread pool as a pool, using a thread pool is overkill. Just create a thread group and start your threads.
private final ThreadGroup normalPriorityThreadGroup = new ThreadGroup("NormalPriority");
for (int i = 0; i < 30; i++) {
new Thread(this.normalPriorityThreadGroup, runnable, "NormalPriority-" + 1).start();
}
if (this.normalPriorityThreadGroup.activeCount() == 0) {
log.error("No Normal Priority response listeners available. Shutting down App!");
System.exit(1);
}

How to check if the threads have completed its task or not?

OK, I created couples of threads to do some complex task. Now How may I check each threads whether it has completed successfully or not??
class BrokenTasks extends Thread {
public BrokenTasks(){
super();
}
public void run(){
//Some complex tasks related to Networking..
//Example would be fetching some data from the internet and it is not known when can it be finished
}
}
//In another class
BrokenTasks task1 = new BrokenTasks();
BrokenTasks task2 = new BrokenTasks();
BrokenTasks task3 = new BrokenTasks();
BrokenTasks task4 = new BrokenTasks();
task1.start();
.....
task4.start();
So how can I check if these all tasks completed successfully from
i) Main Program (Main Thread)
ii)From each consecutive threads.For example: checking if task1 had ended or not from within task2..
A good way to use threads is not to use them, directly. Instead make a thread pool. Then in your POJO task encapsulation have a field that is only set at the end of computation.
There might be 3-4 milliseconds delay when another thread can see the status - but finally the JVM makes it so. As long as other threads do not over write it. That you can protect by making sure each task has a unique instance of work to do and status, and other threads only poll that every 1-5 seconds or have a listener that the worker calls after completion.
A library I have used is my own
https://github.com/tgkprog/ddt/tree/master/DdtUtils/src/main/java/org/s2n/ddt/util/threads
To use : in server start or static block :
package org.s2n.ddt.util;
import org.apache.log4j.Logger;
import org.junit.Test;
import org.s2n.ddt.util.threads.PoolOptions;
import org.s2n.ddt.util.threads.DdtPools;
public class PoolTest {
private static final Logger logger = Logger.getLogger(PoolTest.class);
#Test
public void test() {
PoolOptions options = new PoolOptions();
options.setCoreThreads(2);
options.setMaxThreads(33);
DdtPools.initPool("a", options);
Do1 p = null;
for (int i = 0; i < 10; i++) {
p = new Do1();
DdtPools.offer("a", p);
}
LangUtils.sleep(3 + (int) (Math.random() * 3));
org.junit.Assert.assertNotNull(p);
org.junit.Assert.assertEquals(Do1.getLs(), 10);
}
}
class Do1 implements Runnable {
volatile static long l = 0;
public Do1() {
l++;
}
public void run() {
// LangUtils.sleep(1 + (int) (Math.random() * 3));
System.out.println("hi " + l);
}
public static long getLs() {
return l;
}
}
Things you should not do:
* Don't do things every 10-15 milliseconds
* Unless academic do not make your own thread
* don't make it more complex then it needs for 97% of cases
You can use Callable and ForkJoinPool for this task.
class BrokenTasks implements Callable {
public BrokenTasks(){
super();
}
public Object call() thrown Exception {
//Some complex tasks related to Networking..
//Example would be fetching some data from the internet and it is not known when can it be finished
}
}
//In another class
BrokenTasks task1 = new BrokenTasks();
BrokenTasks task2 = new BrokenTasks();
BrokenTasks task3 = new BrokenTasks();
BrokenTasks task4 = new BrokenTasks();
ForkJoinPool pool = new ForkJoinPool(4);
Future result1 = pool.submit(task1);
Future result2 = pool.submit(task2);
Future result3 = pool.submit(task3);
Future result4 = pool.submit(task4);
value4 = result4.get();//blocking call
value3 = result3.get();//blocking call
value2 = result2.get();//blocking call
value1 = result1.get();//blocking call
And don't forget to shutdown pool after that.
Classically you simply join on the threads you want to finish. Your thread does not proceed until join completes. For example:
// await all threads
task1.join();
task2.join();
task3.join();
task4.join();
// continue with main thread logic
(I probably would have put the tasks in a list for cleaner handling)
If a thread has not been completed its task then it is still alive. So for testing whether the thread has completed its task you can use isAlive() method.
There are two different questions here
One is if the thread still working.
The other one is if the task still not finished.
Thread is a very expensive method to solve problem, when we start a thread in java, the VM has to store context informations and solve synchronize problems(such as lock). So we usually use thread pool instead of directly thread. The benefit of thread pool is that we can use few thread to handle many different tasks. That means few threads keeps alive, while many tasks are finished.
Don’t find task status from a thread.
Thread is a worker, and tasks are jobs.
A thread may work on many different jobs one by one.
I don’t think we should ask a worker if he has finished a job. I’d rather ask the job if it is finished.
When I want to check if a job is finished, I use signals.
Use signals (synchronization aid)
There are many synchronization aid tools since JDK 1.5 works like a signal.
CountDownLatch
This object provides a counter(can be set only once and count down many times). This counter allows one or more threads to wait until a set of operations being performed in other threads completes.
CyclicBarrier
This is another useful signal that allows a set of threads to all wait for each other to reach a common barrier point.
more tools
More tools could be found in JDK java.util.concurrent package.
You can use Thread.isAlive method, see API: "A thread is alive if it has been started and has not yet died". That is in task2 run() you test task1.isAlive()
To see task1 from task2 you need to pass it as an argument to task2's construtor, or make tasks fields instead of local vars
You can use the following..
task1.join();
task2.join();
task3.join();
task4.join();
// and then check every thread by using isAlive() method
e.g : task1.isAlive();
if it return false means that thread had completed it's task
otherwise it will true
I'm not sure of your exact needs, but some Java application frameworks have handy abstractions for dealing with individual units of work or "jobs". The Eclipse Rich Client Platform comes to mind with its Jobs API. Although it may be overkill.
For plain old Java, look at Future, Callable and Executor.

Java threadpools and runnables creating runnables

Bear with me as I'm not terribly savvy in multithreaded programming...
I'm currently building out a system that uses a ThreadPool ExecutorService for various runnables. That much is straightforward. However, I'm looking at the possibility of having the runnables themselves spawn an additional runnable based on what happens in the original runnable (ie, if success, do this, if fail, do this, etc as some tasks must be complete before others execute). It should be noted that the main thread does not need to be notified of the results of these tasks, although it might be handy for handling exceptions, ie, if an external service cannot be contacted and all threads are throwing exceptions as a result, then stop submitting tasks and periodically check on the external service until it comes back up. This isn't completely necessary, but it would be nice.
Ie, submit Task A. Task A does some things. If everything goes well, Task A will execute Task B. If something doesn't work out properly or an exception is thrown, execute Task C. Each child task may also have additional tasks, but only a few levels deep. I'd much rather do something like this than large, snarled conditionals in a single task as this approach allows for much greater flexibility.
However, I'm not certain how this would affect the thread pool. I would assume that any additional thread(s) created from within a thread in the pool would exist outside of the pool as they themselves were not submitted directly to the pool. Is this a correct assumption? If so, it's likely a bad idea (well, if not, it may not be a very good idea anyway) as it could result in a lot more threads as the original thread completes and a new task is submitted while the thread spawned from the earlier task is still going (and may last considerably longer than others).
I've also considered implementing these as Callables instead and placing a response object in the Future that is returned, then add the appropriate Callable to the thread pool based on the response. However, this would tie all actions back to the main thread, which seems an unnecessary bottleneck. I suppose I could place a Runnable into the pool that itself handles the execution of the Callable and subsequent actions, but then I get twice as many threads.
Am I on the right track here or am I completely off the rails?
I have never used this, but it can be useful for you: http://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html
There are many ways to do what you want. You need to be careful you don't end up creating too many threads.
The following is an example, you could make this more efficient with an ExecutorCompletionService and alternatively you could use Runnable's.
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadsMakeThreads {
public static void main(String[] args) {
new ThreadsMakeThreads().start();
}
public void start() {
//Create resources
ExecutorService threadPool = Executors.newCachedThreadPool();
Random random = new Random(System.currentTimeMillis());
int numberOfThreads = 5;
//Prepare threads
ArrayList<Leader> leaders = new ArrayList<Leader>();
for(int i=0; i < numberOfThreads; i++) {
leaders.add(new Leader(threadPool, random));
}
//Get the results
try {
List<Future<Integer>> results = threadPool.invokeAll(leaders);
for(Future<Integer> result : results) {
System.out.println("Result is " + result.get());
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
threadPool.shutdown();
}
class Leader implements Callable<Integer> {
private ExecutorService threadPool;
private Random random;
public Leader(ExecutorService threadPool, Random random) {
this.threadPool = threadPool;
this.random = random;
}
#Override
public Integer call() throws Exception {
int numberOfWorkers = random.nextInt(10);
ArrayList<Worker> workers = new ArrayList<Worker>();
for(int i=0; i < numberOfWorkers; i++) {
workers.add(new Worker(random));
}
List<Future<Integer>> tasks = threadPool.invokeAll(workers);
int result = 0;
for(Future<Integer> task : tasks) {
result += task.get();
}
return result;
}
}
class Worker implements Callable<Integer> {
private Random random;
public Worker(Random random) {
this.random = random;
}
#Override
public Integer call() throws Exception {
return random.nextInt(100);
}
}
}
Submitting tasks to the thread pool from other tasks is quite meaningful idea. But I am afraid you think of running new tasks on separate threads, that really can eat all the memory. Just set a limit to the number of threads when the pool is created, and submit new tasks to that thread pool.
This approach can be further elaborated in different directions. First, treat tasks as ordinary objects, with interface methods, and let that methods decide if they want to submit this object to the thread pool. This requires that each task knows its thread pool - pass it as a parameter at the time of creation. Even more convenient, keep reference to the thread pool as a thread local variable.
You can easily emulate functional programming: an object represents a function call, and for each parameter it has corresponding set method. When all parameters are set, the object is submitted to the thread pool.
Another direction is actor programming: task class has single set method, but it can be called multiple times, and if previous argument is not yet processed, the set method does not submit the task to the thread pool, but simply stores its argument in a queue. The run() method processes all available arguments from the queue and then returns.
All this features are implemented in the dataflow library https://github.com/rfqu/df4j. I wrote it intentionally to support task-based parallelism.

How to test IO issues in Java?

How can I test behavior of my application code for the case of very bad IO performance without using mock streams that sleep (because they would react to interrupts)?
For instance, I want to test a ConcurrentWrapper utility that has a pool of threads for file IO. It submits each operation to an ExecutorService with invokeAll() with timeout. I want to confirm not only that the call with ConcurrentWrapper exits before timeout, but also that it somehow made the thread of its inner ExecutorService terminate (to avoid leakage).
I need to somehow simulate slow IO in the inner thread, but in a way that will ignore interrupts (like real IO does).
A bit of clarification: No answer like "sleep and swallow InterruptedException" or "sleep, catch InterruptedException and go back to sleep" is acceptable. I want to test how my code handles interrupts and such instrumentation would defeat the purpose by handling them itself.
You can sleep in a way that will insist on sleeping through interrupts:
long start = System.currentTimeMillis();
long end = start + sleepTime;
for (long now = start; now < end; now = System.currentTimeMillis()) {
try {
Thread.sleep(end - now);
} catch (InterruptedException ignored) {
}
}
For testing with timeouts, you can actually put a maximum time to execute the test, in JUnit you can include the annotation timeout:
#Test(timeout=100)
public void method_withTimeout() {
while(true);
}
For the part of testing that the method exits, you could use the Future interface that provides a timeout for getting the results.
If i understand your question correctly, ReentrantLock might help.
final ReentrantLock lock = new ReentrantLock();
Callable<Void> c = new Callable<Void>() {
public void call() {
lock.lock();
try {
if (Thread.currentThread().isInterrupted()) {
...
}
}
finally {
lock.unlock();
}
}
}
// Submit to the pool
Future<Void> future = executorService.submit(c);
// you might want to sleep a bit to give the pool a chance
// to pull off the queue.
// Issue a cancel
future.cancel();
// Now release the lock, which should let your
// callable continue onto to the interrupted check.
lock.unlock();
Note that the "lock" method does not throw any InterruptedException (though there is a method for that called "lockInterruptibly"), and if you look at the code for that class, it's not catching and swallowing (as you've stated would not be what you want).

Threads are destroyed?

I create a pool of threads with an Executors.newFixedThreadPool, but after a time I noticed that some of them stoped to answer (call this method below).
They was destroyed? I doing synchonization and the system continues when all threads set that finished the task, but with this, the system enter in deadlock.
They was destroyed? What can I do to prevent or handle this?
//this is the method that threads call when finish the work
synchronized void setTaskFinish(){
System.out.println(Thread.currentThread().getName() + " finishing the work.");
finishedThreads++;
System.out.println(finishedThreads +" finished the work.");
if(finishedThreads == numberThreads){
finishedThreads = 0;
this.notify();
}
}
//this is the method that creates the thread
//I dont know much about this executors yet, so I think it have errors
public void execute(int numberThreads) {
for (int i = 0; i < numberThreads; i++) {
crawlers.add(new SlaveCrawler());
}
ExecutorService threadExecutor = Executors.newFixedThreadPool(numberThreads);
for (int i = 0, n = crawlers.size(); i < n; i++) {
threadExecutor.execute((Runnable) crawlers.get(i));
}
threadExecutor.shutdown();
}
EDIT: I changed entirely my logic. I have not done much testing, but everything seems ok now. Maybe it was something wrong in my old logic.
The executor won't destroy threads that are busy executing your tasks. If you assigned 60 tasks, and only 55 "complete" (more precisely, your setTaskFinish() method is only invoked 55 times), it could be an exception terminating your task prematurely. Deadlock is another possibility, but not the first I would examine.
What happens when your task throws an unchecked exception like RuntimeException? Does it call setTaskFinish() from a finally block? Why are you managing concurrency using synchronized instead of an AtomicInteger?

Categories