我想运行一些简单的后台进程计算,但我似乎无法弄清楚。不管我做什么,它都会阻塞。
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!按预期显示多次,但不允许 Web 应用程序联机。