jpp*_*ade 62 java multithreading
我在我的tomcat服务器上获得此异常(+ liferay)
java.util.concurrent.RejectedExecutionException
Run Code Online (Sandbox Code Playgroud)
我的课就是这样的:
public class SingleExecutor extends ThreadPoolExecutor {
public SingleExecutor(){
super(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
}
@Override
public void execute(Runnable command) {
if(command instanceof AccessLogInsert){
AccessLogInsert ali = (AccessLogInsert)command;
ali.setConn(conn);
ali.setPs(ps);
}
super.execute(command);
}
}
Run Code Online (Sandbox Code Playgroud)
我在行上遇到此异常super.execute(command);
当队列已满但LinkedBlockingQueue
大小为2 ^ 31时,可能会发生此错误,我确信没有这么多命令等待.
一开始一切都很稳定,但在重新部署战争之后它就开始了.这个类不是战争的一部分,而是在tomcat/lib的jar中.
你知道为什么会发生这种情况以及如何解决这个问题吗?
Sto*_*ica 71
来自ThreadPoolExecutor JavaDoc
execute(java.lang.Runnable)
当Executor
关闭时,以及当Executor
使用最大线程和工作队列容量的有限边界并且饱和时,将拒绝在方法中提交的新任务.在任何一种情况下,execute方法都会调用它的RejectedExecutionHandler.rejectedExecution(java.lang.Runnable, java.util.concurrent.ThreadPoolExecutor)
方法RejectedExecutionHandler
.提供了四种预定义的处理程序策
- 在默认情况下
ThreadPoolExecutor.AbortPolicy
,处理程序RejectedExecutionException
在拒绝时抛出运行时.- 在
ThreadPoolExecutor.CallerRunsPolicy
,调用execute本身的线程运行任务.这提供了一种简单的反馈控制机制,可以降低新任务的提交速度.- 在
ThreadPoolExecutor.DiscardPolicy
,简单地删除无法执行的任务.- 在
ThreadPoolExecutor.DiscardOldestPolicy
,如果执行程序未关闭,则删除工作队列头部的任务,然后重试执行(可能再次失败,导致重复执行).可以定义和使用其他
RejectedExecutionHandler
类.这样做需要一些小心,特别是当策略设计为仅在特定容量或排队策略下工作时.
因此,据推测,重新加载战争会导致关闭战争Executor
.尝试将相关的库放入战争中,以便Tomcat ClassLoader
有更好的机会正确地重新加载你的应用程序.
只是为了增加OrangeDog的出色答案,an的约定Executor
的确是这样,当执行程序饱和时(即队列中没有空间),其execute
方法将抛出RejectedExecutionException
。
但是,如果阻止它,而是自动等待直到队列中有新任务的空间,它将很有用。
使用以下自定义BlockingQueue
可以实现:
public final class ThreadPoolQueue extends ArrayBlockingQueue<Runnable> {
public ThreadPoolQueue(int capacity) {
super(capacity);
}
@Override
public boolean offer(Runnable e) {
try {
put(e);
} catch (InterruptedException e1) {
return false;
}
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
这实质上实现了背压算法,每当执行程序饱和时,都会降低生产者的速度。
用作:
int n = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor executor = new ThreadPoolExecutor(0, n, 1, TimeUnit.MINUTES, new ThreadPoolQueue(n));
for (Runnable task : tasks) {
executor.execute(task); // will never throw, nor will queue more than n tasks
}
executor.shutdown();
executor.awaitTermination(1, TimeUnit.HOURS);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
58730 次 |
最近记录: |