JDK-6648211 : Need for blocking ThreadPoolExecutor
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.util.concurrent
  • Affected Version: 6
  • Priority: P5
  • Status: Open
  • Resolution: Unresolved
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2008-01-08
  • Updated: 2011-02-16
Related Reports
Relates :  
Description
A DESCRIPTION OF THE REQUEST :
ThreadPoolExecutor is a very flexible Executor class to achieve multi threading in a simple way. However, due to the lack of blocking nature, its use is limited.

I find 2 discussions related to this issue.

http://www.ibm.com/developerworks/forums/message.jspa?messageID=13785440
http://forum.springframework.org/showthread.php?t=35869

JUSTIFICATION :
This is a typical requirement in any multi threaded enterprise application.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
It would be nice if ThreadPoolExecutor.submit() or ThreadPoolExecutor.execute() method block until a thread gets freed up for picking up a new task.
ACTUAL -
In the current implementation ThreadPoolExecutor.submit() and ThreadPoolExecutor.execute() methods throw RejectedExecutionException exception after the configured # of threads get busy.

---------- BEGIN SOURCE ----------
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class BlockingThreadPoolExecutor {

	public static void main(String[] args) {
		ArrayBlockingQueue jQ = new ArrayBlockingQueue(3);
		ThreadPoolExecutor tpExe = new ThreadPoolExecutor(1, 3, 30, TimeUnit.SECONDS,jQ );
		int numJobs = 10;
		
		System.out.println("Starting application to add "+ numJobs + " jobs");
		
		for (int i=1; i<= numJobs; i++)
			try {
				tpExe.submit(new WorkerThread(i));
				System.out.println("Added job #" + (i));
			}
		   	catch (RejectedExecutionException e) {
		      System.err.println("RejectedExecutionException");
		   }
		}

	}
	class WorkerThread implements Runnable {
		int jobId;
		public WorkerThread (int jobId){
			this.jobId = jobId;
		}
		public void run (){
			try{
				Thread.sleep(1000);
			}catch (Exception excep){}
		}
	}
---------- END SOURCE ----------

Comments
EVALUATION Brian Goetz points out an excellent solution using a Semaphore in http://www.ibm.com/developerworks/forums/message.jspa?messageID=13785440 so there seems to be no need for this feature. I would like to see improvements to task submission for another reason, namely to avoid creating a new Thread when a waiting idle thread is available. 6452337: ThreadPoolExecutor should prefer reusing idle threads I see that the Prometheus project http://prometheus.codehaus.org/overview.html has a BlockingExecutor, but I am not sure this is a good design. Perhaps best would be to add to the documentation of TPE explaining how to layer on blocking.
09-01-2008