繁体   English   中英

如何使用Spring TaskExecutor在应用程序的所有请求中使用单个任务池

[英]How to use a single Task Pool across all request for an application using Spring TaskExecutor

我如何使用spring TaskExecutor生成任务,以便不抛出outof memory异常。

当前任务池配置:

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
  <property name="corePoolSize" value="56" />
  <property name="maxPoolSize" value="112" />
  <property name="queueCapacity" value="100" />
</bean>
<bean id="threadExecutor" class="com.content.ThreadHandler.ThreadExecutor">
  <constructor-arg ref="taskExecutor" />
</bean>
</beans>

我通过使用load bean在我的请求处理程序中使用bean:

ApplicationContext context=new ClassPathXmlApplicationContext(new String[]{"ThreadPoolConfig.xml"});
            BeanFactory factory=context;

            ThreadExecutor myBean=(ThreadExecutor)factory.getBean("threadExecutor");

然后我使用taskexecutor作为mybean.execute(任务);

此配置是否为每个请求创建一个新池?

建议1

您不应该为每个请求实例化Spring应用程序上下文。 你应该有一个名为SpringContext的单例类或类似的东西,它应该只实例化一次Spring应用程序上下文。 所以你的客户端代码应该是

ThreadExecutor myBean=(ThreadExecutor)SpringContext.getInstance().getBean("threadExecutor");

如前所述,SpringContext应该只是一个普通的单例类; 在初始化方法中,您将实例化spring applicationcontext。

public class SpringContext {

   public ClassPathXmlApplicationContext context;

   private static SpringContext _instance = new SpringContext();

   private SpringContext() {
      context = new ClassPathXmlApplicationContext(new String[]{"ThreadPoolConfig.xml"});
   }

   public static SpringContext getInstance() {
      return _instance;
   }


   public Object getBean(String bean) {
      Object beanObj = (context != null) ? context.getBean(bean) : null;
      return beanObj;
   }

}

建议2

如果这不起作用,那么你应该看看以下内容:

spring bean元素具有scope属性。 您可以在其中指定的两个值是request和session,对应于HTTPRequest和HTTPSession。 在您的情况下尝试使用其中一个。 http://static.springsource.org/spring/docs/3.0.x/reference/beans.html#beans-factory-scopes

所以你的bean定义看起来应该是这样的

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" scope="session">

您是否为每个请求创建一个新的ClassPathXmlApplicationContext? 在这种情况下,您将为每个请求创建一个新池,这将是非常低效的。

从你收到OutOfMemory错误的事实来看,我会认为你是。 确保在使用完上下文后调用了context.destroy(),否则垃圾收集将不会收集bean使用的所有内存,并且每次请求都会泄漏您的应用程序。

通常(如果我们讨论的是Web应用程序),您将使用web.xml中的ContextLoaderListener来创建单个WebApplicationContext,这意味着您只使用一个池。

请注意,如果您正在讨论Web应用程序,创建自己的线程池通常是不明智的,因为这些线程将不会由应用程序服务器管理,这会通过在服务器实例上拥有两个线程来对性能产生负面影响(除非您使用的是工作经理

编辑:有关ContextLoaderListener的更多信息,请参阅此处

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM