Reputation: 4930
I am currently working on an application that has in its main layout a ListView
, its items are wrappers for real files contained in a directory.
When the list is populated I execute an AsyncTask that should retrieve some data from a Properties
file and, if such data is not retrieved, I add a Runnable
to a ThreadPoolExecutor
to get that data from a website, save it into the Properties
and then load the Properties
.
If I decide to change the directory, a List.clear()
is performed before the app populates it with the new items.
As a consequence, if there are currently working/pending Thread
s inside the ThreadPoolExecutor
, they continue being executed and make my application crash, because the item inside the List
doesn't exist anymore.
I've read some questions but none of them satisfied me. How can I prevent currently active Thread
s from accessing the List and empty the queue of the ThreadPoolExecutor
? Alternatively, how can I design a runnable in such way that if it's not needed anymore it doesn't interfere with the List
?
Update:
In my method to repopulate the List
I did the following before doing clear()
:
if(mBlockingQueue.size()>0){
mBlockingQueue.drainTo(new ArrayList<Runnable>()); //I don't want to keep the workers
mThreadPoolExecutor.shutDownNow(); //This will execute .interrupt(); on the working Threads
}
Update2: This is not enough: After creating your executor use the following
myThreadPoolExecutor.setRejectedExecutionHandler(new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r,ThreadPoolExecutor executor) {
//Do nothing
}
});
Upvotes: 2
Views: 456
Reputation: 1803
You can use this code to have a paused tasks list:
BlockingQueue<Runnable> queue = threadPool.getQueue();
List<Runnable> list = new ArrayList<Runnable>();
int tasks = queue.drainTo(list);
Then you can follow this documentation and find a way to use remove on the BlockingQueue
Upvotes: 1