我有一个基于JSP的(java)Web应用程序。在这个应用程序中,我可以通过执行外部命令,向机器(PC)询问基于IP的状态和实际操作系统。
为了加快请求,我想要使用线程同时要求更多的机器,即ExecutorService。
相应View的preRenderView侦听器设置为此方法,我收集所有必须显示的数据。这里我初始化执行程序,它被声明为私有静态类字段(public void selectData( ComponentSystemEvent event )
{
AmtRoomMachinesListController.executor = Executors.newFixedThreadPool(20);
AmtRoomMachinesListModel amtRoomMachinesListModel = (AmtRoomMachinesListModel)getModel();
List< ListRow > listRows = fetchListRows( amtRoomMachinesListModel );
...
}
):
fetchListRow
在private List< ListRow > fetchListRows( AmtRoomMachinesListModel amtRoomMachinesListModel )
{
...
List< ListRow > listRows = Collections.synchronizedList( new ArrayList< ListRow >() );
for ( Machine machine : room.getRoomPCs() )
{
executor.submit( new AmtcWorker( listRows, machine, amtRoomMachinesListModel ) );
}
executor.shutdown();
try
{
executor.awaitTermination( 20, TimeUnit.SECONDS );
}
catch ( InterruptedException e )
{
throw new BootrobotException( ExceptionType.AMTC_ERROR, "command", "Waiting for thread termination", "error", e.getMessage() );
}
((ThreadPoolExecutor)executor).purge();
LOGGER.info( "Executor is shut down: " + executor.isShutdown() );
LOGGER.info( "Executor is terminated: " + executor.isTerminated() );
sortListRows( listRows );
return listRows;
}
中调用执行程序并提交可调用程序。然后关闭并终止执行程序:
selectData
我的问题是进程/线程的数量不断增加,一段时间后我得到了OutOfMemory异常。每次调用res = opener.open(login_url, data)
res.close()
时,进程数都会增加提示机器的数量。
我是新手与线程,但我认为执行者会在调用executor.shutdown()或executor.awaitTermination或executor.purge()时终止/终止它们来处理生成的线程。 / p>
我错过了什么?
答案 0 :(得分:1)
使用一个ThreadPool。另外,你确认awaitTermination函数返回true吗?很可能awaitTermination在20秒内没有完成并返回false。新的线程池不断创建,而没有旧的线程池获得GCed并最终耗尽内存。
答案 1 :(得分:1)
我的建议是只创建一个线程池。线程池用于管理线程。如果你每次调用一个方法创建一个线程池,那么基本上它就像你每次调用一个方法时创建线程一样糟糕,但是如果你仍然坚持要创建多个线程池那么为什么不要你呢?试试这个
private List< ListRow > fetchListRows( AmtRoomMachinesListModel amtRoomMachinesListModel )
{
ExecutorService executor = Executors.newFixedThreadPool(20);
...
List< ListRow > listRows = Collections.synchronizedList( new ArrayList< ListRow >() );
for ( Machine machine : room.getRoomPCs() )
{
executor.submit( new AmtcWorker( listRows, machine, amtRoomMachinesListModel ) );
}
executor.shutdown();
try
{
executor.awaitTermination( 20, TimeUnit.SECONDS );
}
catch ( InterruptedException e )
{
throw new BootrobotException( ExceptionType.AMTC_ERROR, "command", "Waiting for thread termination", "error", e.getMessage() );
}
((ThreadPoolExecutor)executor).purge();
LOGGER.info( "Executor is shut down: " + executor.isShutdown() );
LOGGER.info( "Executor is terminated: " + executor.isTerminated() );
sortListRows( listRows );
return listRows;
}
刚刚本地化了执行者