我有一个java服务器正在处理客户请求的网页中的图像。
现在处理这些图像需要时间和内存,并且进入处理图像的n个线程会挂起服务器。
现在为了避免处理图像的代码,我将它们放在Runnable类中并从执行程序池中调用它们。
我的问题是,以下实现是否是在服务器中执行Executor池的正确方法。
Runnable类是 -
public class MyRunnable implements Runnable {
private final String id;
MyRunnable(String tid) {
this.id = tid;
}
@Override
public void run() {
NewAlbumImage nai = new NewAlbumImage();
nai.save_image(id,false);
}
}
运行Runnable类的代码如下 -
newa.NewClass newca = new newa.NewClass();
Runnable mr = new MyRunnable(id);
newca.executor.execute(mr);
NewClass类有一个静态执行器变量 -
static ExecutorService executor;
我在Web应用程序启动时初始化执行程序变量并在Web应用程序关闭时销毁它 -
public class AppNameServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("Initializing Executor Pool");
NewClass nc = new NewClass();
nc.executor = Executors.newFixedThreadPool(10);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
NewClass nc = new NewClass();
nc.executor.shutdown();
try {
nc.executor.awaitTermination( 10L, TimeUnit.MINUTES);
} catch (InterruptedException ex) {
System.out.println("Executor Pool await Termination exception");
}
}
}
答案 0 :(得分:0)
你提到了
类NewClass有一个静态执行器变量 - static ExecutorService executor;
我建议使用
NewClass.executor.execute(yourRunnableInstance);
NewClass.executor.shutdown();
很容易理解executor
是一个静态字段,您不需要创建多个NewClass
个实例。
其余的代码看起来很好。
答案 1 :(得分:0)
我会考虑一些事情。
首先,您的执行者是静态的。我会使用某种依赖注入框架在需要的地方正确地注入执行程序。或者将它作为属性添加到servlet上下文中,并在servlet初始化时自己注入。
使用ServletContext创建/关闭:
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext context = sce.getServletContext();
context.setAttribute("executor", Executors.newCachedThreadPool());
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
ServletContext context = sce.getServletContext();
ExecutorService executor = (ExecutorService)context.getAttribute("executor");
executor.shutdown();
}
其次,您正在使用固定的线程池。这是一个可能的瓶颈(但也许是故意保存CPU?)。如果没有办法同时调整10张图片的大小,你就可以了。但是,如果处理它们的速率低于请求进入的速率,您将发现固定的线程池不起作用。实际上,如果您的应用程序将响应的调整大小任务加入到用户,则您已将任何给定时刻的可能请求数限制为已定义的线程数。尝试使用缓存的线程池。线程是按需创建的,并且会因不活动而死亡。
Executors.newCachedThreadPool();
最后,我认为这更重要,你的应用程序如何扩展?您拥有的用户越多,您在Web服务器上处理的图像就越多。您的响应时间会很快降低。尝试同时调整图像大小的三个用户可以使用100%的CPU。我建议你把你的图像调整到另一台机器,一个更有能力。