[英]How to implement blocking ThreadPoolExecutor
I need to implement blocking ThreadPoolExecutor
. 我需要实现阻塞
ThreadPoolExecutor
。
This is a very crucial requirement in our enterprise application. 这是我们企业应用程序中非常关键的要求。
It would do something like if ThreadPoolExecutor.submit()
or ThreadPoolExecutor.execute()
method blocks until a thread gets freed up for picking up a new task. 它会像
ThreadPoolExecutor.submit()
或ThreadPoolExecutor.execute()
方法一样阻塞,直到线程被释放以获取新任务。
But in current implementation ThreadPoolExecutor.submit()
and ThreadPoolExecutor.execute()
methods throw RejectedExecutionException exception if all pooled threads get busy. 但是在当前实现中,如果所有池化线程都忙,则
ThreadPoolExecutor.submit()
和ThreadPoolExecutor.execute()
方法会抛出RejectedExecutionException异常。
For example following code throws RejectedExecutionException
: 例如,以下代码抛出
RejectedExecutionException
:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class BlockingTPE {
public static void main(String[] args) {
ArrayBlockingQueue queue = new ArrayBlockingQueue(3);
ThreadPoolExecutor tpExe = new ThreadPoolExecutor(1, 3, 30, TimeUnit.SECONDS, queue);
int numJobs = 50;
for (int i = 1; i <= numJobs; i++) {
try {
tpExe.submit(new WorkerThread(i));
System.out.println("Added#" + (i));
} catch (RejectedExecutionException e) {
e.printStackTrace();
}
}
}
}
class WorkerThread implements Runnable {
int jobId;
public WorkerThread(int jobId) {
this.jobId = jobId;
}
public void run() {
try {
Thread.sleep(1000);
}
catch (Exception excep) {
}
}
}
As the javadoc of ThreadPoolExecutor
states: 正如
ThreadPoolExecutor
的javadoc所述:
Creates a new ThreadPoolExecutor with the given initial parameters and default thread factory and rejected execution handler.
使用给定的初始参数和默认线程工厂以及拒绝的执行处理程序创建新的ThreadPoolExecutor。
The rejected executor handler is an instance of AbortPolicy
which will be called if the queue does not accept another task. 被拒绝的执行程序处理程序是
AbortPolicy
一个实例,如果队列不接受另一个任务,它将被调用。 The behavior as of the javadoc: javadoc的行为:
Always throws RejectedExecutionException.
始终抛出RejectedExecutionException。
Hence the blocking queue does not have any effect for you. 因此阻塞队列对您没有任何影响。 I changed your code this way and it runs without any issues:
我以这种方式更改了代码,它运行没有任何问题:
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
1, 3, 30, TimeUnit.SECONDS, new ArrayBlockingQueue(3));
try {
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
int numJobs = 50;
for (int i = 1; i <= numJobs; i++) {
try {
executor.submit(new WorkerThread(i));
System.out.println("Added#" + (i));
} catch (RejectedExecutionException e) {
e.printStackTrace();
}
}
} finally {
executor.shutdown();
}
}
The decision you have to make is: 你必须做出的决定是:
LinkedBlockingQueue
. LinkedBlockingQueue
。 ThreadPoolExecutor.DiscardPolicy
as rejected execution handler. ThreadPoolExecutor.DiscardPolicy
作为被拒绝的执行处理程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.