Java 空闲固定线程池的缺点
我目前正在一个软件中进行各种性能改进。由于它在GUI中使用SWT,我遇到了一个问题,在某些情况下,在显示线程中创建了许多UI元素。 因为在我之前的那个人没有真正注意到在显示线程之外做任何计算,所以整个软件在启动时可能会在几秒钟内没有响应。 我现在已经隔离了需要在显示线程中执行的代码,并且正在计算提交给固定线程池的可运行文件中的所有其他内容。 我是这样使用游泳池的:Java 空闲固定线程池的缺点,java,multithreading,performance,threadpool,Java,Multithreading,Performance,Threadpool,我目前正在一个软件中进行各种性能改进。由于它在GUI中使用SWT,我遇到了一个问题,在某些情况下,在显示线程中创建了许多UI元素。 因为在我之前的那个人没有真正注意到在显示线程之外做任何计算,所以整个软件在启动时可能会在几秒钟内没有响应。 我现在已经隔离了需要在显示线程中执行的代码,并且正在计算提交给固定线程池的可运行文件中的所有其他内容。 我是这样使用游泳池的: public abstract class AbstractChartComposite { private static Exe
public abstract class AbstractChartComposite {
private static ExecutorService pool = Executors.newFixedThreadPool(8);
private List<String> currentlyProcessingChartItems = new ArrayList<>();
protected void doCalculate(constraints){
for (IMERuntimeConstraint c : constraints) {
if(!currentlyProcessingChartItems.contains(c.getId())){
currentlyProcessingChartItems.add(c.getId());
pool.submit(new Runnable(){
@Override
public void run() {
try{
createChartItem(c);
currentlyProcessingChartItems.remove(c.getId());
}catch(Throwable e){
e.printStackTrace();
}
}
});
}
}
}
}
公共抽象类AbstractChartComposite{
私有静态ExecutorService池=Executors.newFixedThreadPool(8);
private List currentlyProcessingChartItems=new ArrayList();
受保护的空文档计算(约束){
for(IMERuntimeConstraint c:约束){
如果(!currentlyProcessingChartItems.contains(c.getId())){
currentlyProcessingChartItems.add(c.getId());
pool.submit(新的Runnable(){
@凌驾
公开募捐{
试一试{
项目(c);
currentlyProcessingChartItems.remove(c.getId());
}捕获(可丢弃的e){
e、 printStackTrace();
}
}
});
}
}
}
}
我现在想知道,一旦创建了所有UI元素,让线程池空闲运行是否有任何缺点。我不能真的为了垃圾收集而关闭它,因为当需要创建新元素时,在用户输入时会再次需要它。
因此,让线程池不运行提交的可运行程序有什么主要缺点吗?没有,没有缺点 线程将不会实际运行,它们将被暂停,直到提交新任务。所以它不会影响CPU。您还说您将再次使用此池,因此在您的情况下,没有必要关闭它并重新创建 至于内存——是的,空闲线程将消耗一定数量的内存,但这不是一个问题,除非您有数百(数千?)个线程
还有一条建议。不要过早地进行优化。这是万恶之源。一旦出现真正的性能问题,就分析问题,为此使用特殊的实用程序并检测瓶颈。不太可能。只会占用一些记忆。您可以有一个非固定的线程池,它也可以缩小到零。我建议您展示创建线程池时使用的代码。@Thilo所以您可能会建议类似缓存线程池的东西?这听起来是个好主意。请注意,您正在从多个线程(包括修改)访问
ArrayList
(它不是线程安全的)。总有一天会坏掉的。@Holger谢谢,我会在我的代码中修复它谢谢你的建议。不过,这并非为时过早。我们的目标是让我们的软件工作一周以上,而以前它总是因为内存问题而崩溃。多年来,它也变得相当迟钝。启动过程中10秒的冻结已经不是我们想要容忍的了。这就是为什么我目前正在研究使用Visual VM、MAT for heapdump分析和其他一些工具进行各种优化的原因。@Radio,不客气。在这种情况下,调整线程池并不是您真正想要做的:)关注系统的其他部分。回答得好。我想补充一点,当不再需要线程池时,或者当应用程序退出时,一定要关闭线程池。否则,程序结束后线程可能会继续。@PavelSmirnov谢谢。我只是想确保在优化时不会出现任何新问题。顺便说一句,如果这些空闲线程仍然是一个问题,您可以轻松地将执行器替换为新线程池执行器(0,8,1L,TimeUnit.MINUTES,new LinkedBlockingQueue())
。然后,一个线程在空闲至少一分钟时会被终止,但在需要时会被重新创建。与newFixedThreadPool
的实现相比,变化很小。但无论如何,答案是正确的,八个空闲线程不会伤害任何人。