2

I have a ThreadPool in my android application where I run a bunch of threads in different situation in it.

public class ThreadPoolExecuter {

    private final ExecutorService mExecuter;
    private static final int nThreads = 5;

    private ThreadPoolExecuter() { 
        this.mExecuter = Executors.newFixedThreadPool(nThreads);
    }

Java ThreadPool have no default to cancel thread. One solution that I thought about was keeping a key-value pairs of Future when I submit runnable.

public void add(Runnable runnable) {
    Future<?> future = this.mExecuter.submit(runnable);
    // Add future to my key-value pairs
    if(Constant.DEBUG) Log.d(TAG, "Task submitted.");
}

And then have a cancel function:

public boolean cancel(KEY) {
   Future<?> future = map.get(KEY)
   return future.cancel(mayInterruptIfRunning);
}

Let's say a HashMap. The value is the Future, what about key? 1)What is your suggestion?

Map<Key, Future<?>> map = new HashMap()<key, Future<?>>;

About the key I thought about passing an id for every runnable as follows:

2)what do you think about this solution?

But I would mention that in my runnable class sometimes I faced with InterruptedException. Is there any way to avoid it?

class Runner implements Runnable {

    private int id;

    public Runner(int id) {
        this.id = id;
    }

    @Override
    public void run() {

        System.out.println("Starting " + id);
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            System.out.println("Crashed on:" + Thread.currentThread().getId());
        }
        System.out.println("ending " + id);
    }
}

3 ) At the end I want to add it is important for me to know any better solution in your point of view to develop a cancel function in java ThreadPool?

Notice that I don't look for a replacement for my ThreadPool such as AsyncTask in Android which has default cancellation.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Ali
  • 9,800
  • 19
  • 72
  • 152
  • Why do you want to have `KEY` instead of having the actual `Future`? – pingw33n May 30 '14 at 08:59
  • There could be a bunch of threads running in the Pool. `this.mExecuter = Executors.newFixedThreadPool(nThreads);` I want to detect one of them and cancel that specific one, while others are running normally. – Ali May 30 '14 at 09:01
  • This is what is `Future` instance for, you don't have to add another level on indirection unless you need to expose it outside of the JVM. – pingw33n May 30 '14 at 09:06
  • Ok, so maybe I can keep a list of Future (List>) in my ThreadPool class. Sometimes I faced with InterruptedException, do you know how can I avoid it? (it is just sometimes) – Ali May 30 '14 at 09:12
  • 1
    Why do you want to keep the list? Do you at some point need to cancel all the tasks at once? On how to handle `InterrputedException` see: http://stackoverflow.com/questions/3976344/handling-interruptedexception-in-java – pingw33n May 30 '14 at 09:17
  • Yes maybe the only point to keep a list is to cancel all the tasks at once. But maybe `shutdownNow` is a better option. Thanks for the link. – Ali May 30 '14 at 09:33
  • Definitely `shutdownNow` with the properly handled `InterrputedException`s is the way to go. – pingw33n May 30 '14 at 09:40
  • @pingw33n, you can share your answer, so I can mark as accepted. – Ali Jun 09 '14 at 19:40

2 Answers2

1

Since your primary need is to be able to cancel all running tasks at once you should be able to use shutdownNow() of the ExecutorService. Default ExecutorService implementations will call Thread.interrupt() in order to abort the running threads so you should handle InterrputedException properly (by closing any resources used and exiting the thread).

pingw33n
  • 12,292
  • 2
  • 37
  • 38
0

Generally cancelling threads from outside the thread itself contains all sorts of risks that aren't obvious at first. A safer approach is to have the thread when it starts check to see whether it still needs to run.

Tim B
  • 40,716
  • 16
  • 83
  • 128