开发者

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

开发者 https://www.devze.com 2023-03-25 04:09 出处:网络
How do i use the spring TaskExecutor to spawn tasks such that the outof memory exception are not thrown.

How do i use the spring TaskExecutor to spawn tasks such that the outof memory exception are not thrown.

Current task pool configuration:

<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>

and i am using the bean in my request handler by using the load bean as:

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

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

and then i use the taskexecutor as mybe开发者_运维知识库an.execute(task);

Does this configuration create a new pool for each request?


SUGGESTION 1

You shouldn't be instantiating the Spring application context for each request. You should have a singleton class named SpringContext or something like that and that should instantiate the Spring application context only once. So your client code should just be

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

As mentioned earlier, the SpringContext should just be a regular singleton class; where in the initialization method, you will instantiate the 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;
   }

}

SUGGESTION 2

In case this doesn't work, then you should look into the following :

The spring bean element has a scope attribute. Two of the values you can specify there are request and session, corresponding to HTTPRequest and HTTPSession. Try using one of them in your case. http://static.springsource.org/spring/docs/3.0.x/reference/beans.html#beans-factory-scopes

So your bean definition should look something like

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


Are you creating a new ClassPathXmlApplicationContext for every request? In that case you would create a new pool for every request, which would be very inefficient.

Judging from the fact that you are getting OutOfMemory errors, I would assume that you are. Make sure that you are calling context.destroy() after you are finished using the context as otherwise the garbage collection will not collect all the memory used by your beans and your app will leak with every request.

Normally (if we're talking about a web application), you'd use the ContextLoaderListener in web.xml to create a single WebApplicationContext which would then mean that you're using only one pool.

Note, if you are talking about a web application, it generally isn't wise to create your own thread pool as these threads won't be managed by the application server, which can negatively influence performance by having two many threads on a server instance (unless you are using a Work Manager)

Edit: for further info on ContextLoaderListener see Here

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号