Is it possible to check if a Runnable's State is State.RUNNING in a thread pool?

Something like this:


ExecutorService threadPool = Executors.newCachedThreadPool();  
Runnable task = new Runnable() {                               
	@Override                                                  
	public void run() {                                        
		int i = 0;                                             
		while (i < 10) {                                       
			try {                                              
				Thread.sleep(2000);                            
			}                                                  
			catch (Exception e) {                              
			}                                                  
			System.out.println("Running" + i);                 
		}                                                      
	}                                                          
};                                                             
                                                               
threadPool.execute(task);                                      
//TODO: Check to see if "task" is still running.               

I wanted to check to see if the Runnable is currently running in the thread pool when the Runnable is executed. Is it possible to do this? The State enumeration is something copied from Thread class. I wasn’t sure if Runnable has one or similar.

Future has the isDone() method. ExecutorService returns a list of Futures.

I see that Futures are for Callables, but I am not sure of Runnables. They (Futures<?>) can be used with Runnables?

I just use Callable instead of Runnable in that case. If that’s somehow horrible practice someone tell me.

Never thought of that before. Thanks for the tip.

Using Callables sounds like the best solution.

But I’m curious:

Can you include an instance variable as part of the Runnable definition? If so, one could set the boolean at the start and unset it when done.

Also, curious about why you need this. The newCachedThreadPool ExecutorService has the ability to tell if a thread in the cache is idle, and can add new threads as demand increases.

I only need one thread that asynchronously do file input/output. And then I would like to GC that ExecutorService since I no longer need it after it had done its file I/O job. It’s just that I don’t know when the file I/O is going to finish.

That is exactly what Futures are for…

Was thrown off by <?>. Have no idea if I should keep it or not?

[quote]Was thrown off by <?>. Have no idea if I should keep it or not?
[/quote]
In case you haven’t read about wildcards before, here is the Java Tutorials explanation:

http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html

ags1 suggestion to use a Future sounds good, but I’d also consider just letting the i/o task be a runnable thread that simply expires when done, and drop the Executor part. However there are things that an Executor provides that you may be wanting. I don’t have a lot of experience here, but I read that with the Executor you can get better error handling than with a raw thread.

There are lots of ways to have the thread notify other components of its completion. Have you ever built your own Listener? The design pattern called “Observer” would be another keyword for a method to search for ideas.

But the ExecutorService does include provisions for shutting it down. For example, if you have just one task, or are giving it the last task, after doing so you can run it’s shutdown() method: “no new tasks are accepted but previously submitted tasks are allowed to complete.” (Goetz, “Java Concurrency in Practice” pg. 121, 6.2.4 Executor lifecycle)

Great book! I am reading that ExecutorService has an awaitTermination() method as well. Maybe overkill for a single i/o task, but still pretty cool.

The thing about that is that you have to actually shutdown() the executor to do awaitTermination(), instead you probably want to call invokeAll() on a List or something of Callables.
invokeAll() will block until all the tasks have finished and then leave the executor waiting for more tasks, which is often the behavior desired. Unless of course you don’t want to use the executor again, then go ahead and use shutdown()/awaitTermination().