如果我的Web应用程序和ejb应用程序在同一台机器上(在同一个JVM上)并且所有ejb调用都是本地调用,那么在将信息从Web传递到ejb时,使用ThreadLocal
会产生任何问题吗? / p>
如果ejb调用是远程的,是否有任何解决方法?从Web应用程序到ejb应用程序是否可以获得ThreadLocal
个信息?在这种情况下是否建议使用ThreadLocal
?
答案 0 :(得分:14)
对于第一个问题,只要在每次调用结束时删除ThreadLocal变量就没有问题。这很重要,因为容器(servlet或ejb)通常使用线程池并因此重用线程,这有两个影响:一个“调用”可能会看到来自前一个调用的线程局部信息,如果从容器中删除一个应用程序而不停止JVM某些类可能不会被垃圾收集,因为它们仍然被容器线程引用。因此,将数据放在try / finally块中的threadlocal中,并在finally部分中删除。
这是一篇文章,展示了处理问题的一种方法:ThreadLocal in web applications
对于第二个问题,因为数据是threadlocal,它不会带有远程调用,你必须在接口中添加一个参数,在一侧提取threadlocal数据并在另一侧重新创建它...
答案 1 :(得分:2)
使用EJB 3.1时,您可以使用EJBContext在context data中传递上下文信息。这只是Map<String,Object>
。
答案 2 :(得分:2)
不应在EJB上下文中使用ThreadLocal。我们不能保证EJB方法调用都在同一个线程上(当然应该是)。
在EJB中,有一种不同的方法调用TransactionSyncrhonizationRegistry。有关详细信息,请参阅Explanation/Usage。
答案 3 :(得分:1)
所有的ejb调用都是本地调用,会使用ThreadLocal创建 时的任何问题
不,你自己回答了你的问题。由于调用是本地调用,因此它们在一个线程的上下文中执行。
如果ejb调用是远程的,是否有任何解决方法?
如果是远程调用,Java EE容器将在另一个JVM中运行,它将生成自己的线程来处理传入的RMI请求,远程Java EE容器无法知道线程局部变量在另一边宣布。将其作为参数对象传递。
答案 4 :(得分:0)
这取决于你传递的信息!第一个问题太笼统了。我建议阅读与ThreadLocal here相关的JavaDoc。
ThreadLocal位于应用程序的服务器端,用于让线程安全地调用Thread对象。
答案 5 :(得分:0)
对于本地调用,ThreadLocal
应该可以正常工作,只要一切都在同一个线程中完成。
对于可能在不同服务器上运行的远程调用,您需要提供其他内容。将所有值作为参数传递(这将起作用,但在代码中引入复杂性)或使用类似分布式缓存的东西,例如: Hazelcast,其功能类似于全局HashMap
,所有群集节点都可以访问。
答案 6 :(得分:0)
ThreadLocal
无法在Web应用程序中100%确定地使用。您根本无法保证一个线程将用于一个会话。在我看来,这可能会很难找到安全漏洞!
ctx.getContextData()
对我不起作用,它总是返回null
!
我也试过TransactionSynchronizationRegistry
,但我也得到null
。
唯一有用的是使用JAAS作为解决方法。但它不是一个好的解决方案。