Weblogic线程池中的ThreadLocal安全性

Jos*_*seK 3 java weblogic java-ee

我正在编写一个使用MDB,EJB的应用程序,并且需要ThreadLocal在多个EJB和Helper类之间传递和记录变量,直到事务完成.

流程是

从MDB onMessage()开始 - >一些业务委托EJB - >一些帮助程序

题:

这个应用程序在Weblogic中运行,Weblogic从它的ThreadPool中重用Threads.那么是否有可能跨线程数据损坏?解决方案使用ThreadLocal.remove()安全吗?

除了将Object作为参数传递给所有方法之外,还有ThreadLocal的替代方法吗?

小智 6

当线程返回池时,WebLogic不会重置用户设置的ThreadLocal变量 - 用户负责管理它们.当重用这些线程时,它们可能会干扰.您可能会遇到内存泄漏,因为未清除线程本地引用.在将线程返回容器之前,您可以安全地重置线程本地.ThreadLocal.remove()调用应该清理它(确保它在finally块中完成)

请注意,如果涉及任何异步或rmi调用,则线程本地将不会传播.您可能需要考虑允许跨线程,客户端和服务器进行上下文传播的WebLogic WorkArea功能.更多详细信息,请访问http://download.oracle.com/docs/cd/E17904_01/web.1111/e13706/context.htm#i1058690


jon*_*one 5

您无法在EJB层中可靠地使用ThreadLocal.即使您的代码现在似乎"正常工作",如果有人远程部署您的某个bean会发生什么?来自EJB限制:

为什么不允许创建和管理线程?

EJB规范为EJB容器分配管理线程的责任.允许企业bean实例创建和管理线程会干扰容器控制其组件生命周期的能力.线程管理不是业务功能,它是一个实现细节,通常是复杂的和特定于平台的.让容器管理线程可以减轻企业bean开发人员处理线程问题的麻烦.多线程应用程序仍然可行,但多线程控制位于容器中,而不是企业bean中.

如果需要共享状态,则应将其作为参数传递给EJB方法.这种方法不适合你吗?另一种选择是临时将其转储到事务登记数据库或缓存中.