我想运行一些简单的后台进程计算,但我似乎无法弄明白。无论我做什么,它都会阻止。
public class WorkThreadManagerContextLoaderListener implements ServletContextListener {
private Runnable runnable;
private WorkManager workManager;
@Override
public void contextInitialized(ServletContextEvent event) {
final WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
workManager = (WorkManager) springContext.getBean("workThreadManager");
runnable = new WorkThreadManagerStartUp(WorkManager);
runnable.run();
}
@Override
public void contextDestroyed(ServletContextEvent event) {
workManager.shutDown();
}
}
WorkThreadManagerStartUp存在的原因是因为我不希望它阻塞因此我将其设置为Runnable类型,并且当调用run()时,它启动ExecutorService:
public class UnitOfWorkThreadManagerStartUp implements Runnable {
private WorkManager workManager;
public UnitOfWorkThreadManagerStartUp(WorkManager workManager) {
this.workManager = workManager;
}
@Override
public void run() {
workManager.startUp();
}
}
public class WorkThreadManager implements WorkManager {
@Autowired
private WorkService workService;
private final int availableProcessors = Runtime.getRuntime().availableProcessors();
private final ExecutorService executorService = Executors.newFixedThreadPool(4 * availableProcessors);
@Override
public void startUp() {
// this method always blocks...
}
}
但我的解决方案无法按预期工作。我正在运行Tomcat 7.0.30。
我想弄清楚的是如何在不停止部署Web应用程序的情况下在后台启动线程池,因为由于startUp()始终阻塞,它目前无法完全联机。我想简化这个解决方案,如果不是真的需要,可能会删除WorkThreadManagerStartUp类。
编辑:
我修改了启动课程
public class WorkThreadManagerStartUp implements Runnable {
private WorkManager workManager;
public WorkThreadManagerStartUp(WorkManager workManager) {
this.workManager = workManager;
}
@Override
public void run() {
try {
while (true) {
System.out.println("Hello World!");
Thread.sleep(1000 * 10);
}
} catch(InterruptedException e) {
System.out.println(e.getMessage());
}
}
}
虽然这是假设在它自己的线程上运行,Hello World!按预期显示多次,但不允许网络应用程序联机。
答案 0 :(得分:1)
查看您的源代码,我看不到实际创建的任何线程。通常,您执行以下操作来分叉线程:
new Thread(new WorkThread(...)).start();
这将调用新线程中的WorkThread.run()
方法。如果您使用的是ExecutorService
(通常推荐使用Thread
的“手动”代码,那么您可以这样做:
executorService.submit(new WorkThread(...));
...
// when done with the service you have to shut it down
executorService.shutdown();
如果您将WorkManager
类注入到侦听器类中,那么我只需在管理器上添加submit(...)
方法,并在侦听器中执行以下操作:
workManager.submit(new WorkThread());
这意味着WorkThreadManagerStartUp
类不是必需的。您将工作线程或工作单元提交给服务。
就Spring而言,我只是制作WorkManager
类工具InitializingBean
和DisposableBean
,以便它可以启动和停止其服务本身。没理由有另一个豆那样做。然后,您可以将管理员注入任何想要使用管理员管理的WorkThread
运行ExecutorService
的班级。