Websphere中ScheduledExecutorService线程是否处于JEE上下文之外?
问题:WebSphere中使用ScheduledExecutorService创建的线程是否脱离JEE上下文?
我在WebSphere里用以下代码按计划异步运行任务:
final Runnable beeper = new Runnable() { public void run() { System.out.println("beep"); } }; ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
我发现这个线程没法访问WebSphere里配置的数据源等资源,怀疑它是在WebSphere的JEE上下文之外运行的。想确认我的这个理解是不是正确的?
回答
没错,你的理解完全正确!
用Executors.newScheduledThreadPool()创建的线程池属于Java SE标准的线程实现,这类线程完全不受WebSphere这类JEE容器的管控,自然也不会携带任何JEE上下文信息——像你提到的数据源、JNDI资源、安全凭证这些容器提供的内容,都没法直接在这类线程里访问到。
要知道,JEE容器管理的线程(比如处理Servlet请求的线程、EJB容器的线程)在启动时会自动绑定容器的上下文环境,当你在这些线程里访问JNDI资源时,容器会自动帮你处理上下文查找的逻辑。但你手动创建的SE线程池完全是脱离容器管控的“野线程”,没有这个上下文绑定的过程,所以在run()方法里尝试查找数据源时,必然会因为找不到容器上下文而失败。
如果你的定时任务需要访问WebSphere里的JEE资源,更推荐使用符合JEE规范或者容器原生的方案:
- EJB定时器(@Schedule注解):这是JEE规范里的标准定时任务方式,完全由容器管理,天生就支持上下文访问,适合轻量级的定时任务场景。
- WebSphere自带的调度服务:比如WebSphere Scheduler,它可以处理更复杂的定时任务需求,同样能正常访问容器内的所有资源。
- 使用容器管理的线程池:如果你一定要用ScheduledExecutorService的API,可以通过JNDI获取WebSphere提供的容器级线程池实例(比如
java:comp/DefaultManagedScheduledExecutorService),这类线程池创建的线程会自动携带JEE上下文,能正常访问数据源等资源。
举个简单的示例代码:
// 获取容器管理的定时线程池 ManagedScheduledExecutorService scheduler = InitialContext.doLookup("java:comp/DefaultManagedScheduledExecutorService"); scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
这样创建的任务线程就会在JEE上下文环境中运行,再也不用担心找不到数据源的问题啦。
内容的提问来源于stack exchange,提问作者anon
相关产品推荐
相关产品推荐

