Cla*_*den 8 java threadpoolexecutor
我正在使用a ThreadPoolExecutor来运行任务.后端是一个SynchronousQueue,所以如果执行程序已经执行了一个任务,它会抛出一个任务RejectedExecutionException.这是一个简单的测试用例:
public class ExecutorTest {
final static Worker worker = new Worker();
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>());
while (true) {
try {
executor.execute(worker);
}catch (RejectedExecutionException e) {
}
}
}
static class Worker implements Runnable {
private int i = 0;
private long start = System.currentTimeMillis();
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println(++i + " " + (System.currentTimeMillis() - start));
} catch (InterruptedException ex) {
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
预期的变化是:执行工作者并在睡眠一秒后打印出i(表示工人到目前为止执行的频率)以及自工人创建以来的毫秒数.所以我期待:
1 1015
2 2015
3 3016
4 4017
Run Code Online (Sandbox Code Playgroud)
这工作正常一段时间,但几乎在一小时后:
2919 2922196
2920 2942951
2921 2990407
Run Code Online (Sandbox Code Playgroud)
因此,一个工人执行与下一个工人执行之间的时间量是20秒(2919-> 2920)和38秒(2920-> 2921)等等.一切都变得非常缓慢,jvm花了很多时间在垃圾收集.最后(几天后)我遇到了OutOfMemoryError.
我在64位Linux机器上的Oracle JVM 1.7.0_07上使用-Xmx8M运行它(我假设后面会有更多堆空间出现效果).我很欣赏任何指针,但可能我只是错过了显而易见的事情.
小智 2
您可以尝试修改ThreadPoolExecutor实例化。您只需向构造函数添加一个参数即可使用RejectExecutionHandler它将默默地丢弃被拒绝的任务。
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>(), new ThreadPoolExecutor.DiscardPolicy());
while (true) {
executor.execute(worker);
}
}
Run Code Online (Sandbox Code Playgroud)
因此,如果你的问题来自重复RejectedExecutionException(我认为是这样),你就会避免它。
| 归档时间: |
|
| 查看次数: |
3860 次 |
| 最近记录: |