14

如果我的 web 应用程序和 ejb 应用程序在同一台机器上(在同一个 JVM 上)并且所有 ejb 调用都是本地调用,那么ThreadLocal在将信息从 web 传递到 ejb 时使用会产生任何问题吗?

如果 ejb 调用是远程的,有什么解决方法吗?ThreadLocal信息是否可以从 Web 应用程序到 ejb 应用程序?ThreadLocal在这种情况下是否建议使用?

4

7 回答 7

14

对于第一个问题,只要在每次调用结束时去掉 ThreadLocal 变量就没有问题。这很重要,因为容器(servlet 或 ejb)通常使用线程池并因此重用线程,这有两个影响:一个“调用”可能会看到来自先前调用的线程本地信息,以及如果您在不停止 JVM 的情况下从容器中删除应用程序有些类可能不会被垃圾回收,因为它们仍然被容器线程引用。因此,将数据放在 try / finally 块中的 threadlocal 中,并在 finally 部分中删除。

这是一篇文章,展示了一种处理问题的方法:Web 应用程序中的 ThreadLocal

对于第二个问题,因为数据是线程本地的,它不会随远程调用一起提供,您必须在接口中添加一个参数,在一侧提取线程本地数据并在另一侧重新创建它......

于 2012-04-26T07:00:10.730 回答
3

使用 EJB 3.1 时,您可以使用 EJBContext 的上下文数据在EJBContext中传递上下文信息。这只是一个.Map<String,Object>

于 2013-01-30T10:19:42.137 回答
3

不应在 EJB 上下文中使用 ThreadLocal。不能保证 EJB 方法调用都在同一个线程上(当然应该如此)。

在 EJB 中有一种不同的方法,称为TransactionSyncrhonizationRegistry。有关详细信息,请参阅说明/用法

于 2013-05-03T07:14:40.917 回答
2

所有 ejb 调用都是本地调用,使用 ThreadLocal 会产生任何问题吗?

不,你自己回答了你的问题。由于调用是本地的,它们在一个线程的上下文中执行。

如果 ejb 调用是远程的,有什么解决方法吗?

在远程调用的情况下,Java EE 容器将在另一个 JVM 中运行,它将产生自己的线程来处理传入的 RMI 请求,远程 Java EE 容器无法知道在其上声明的线程局部变量另一边。将其作为参数对象传递。

于 2012-04-26T07:01:03.223 回答
0

这取决于你传递什么信息!第一个问题太笼统了。我建议在这里阅读与 ThreadLocal 相关的 JavaDoc 。

ThreadLocal 来自应用程序的服务器端,用于让线程安全地调用 Thread 对象。

于 2012-04-26T06:51:16.590 回答
0

对于本地调用,ThreadLocal只要一切都在同一个线程中完成,应该可以正常工作。

对于可能在不同服务器上运行的远程调用,您将需要提出其他方法。要么将所有值作为参数传递(这将起作用,但会在代码中引入复杂性),要么使用分布式缓存之类的东西,例如Hazelcast,它的功能类似于HashMap所有集群节点都可以访问的 global 。

于 2012-04-26T07:05:10.093 回答
0

ThreadLocal不能 100% 确定地在 Web 应用程序中使用。您根本无法保证一个线程将用于一个会话。在我看来,这可能会导致很难找到安全漏洞!

ctx.getContextData()对我不起作用,它总是返回null

我也试过了TransactionSynchronizationRegistry,但我也得到null了。

唯一有效的是使用 JAAS 作为解决方法。但这不是一个好的解决方案。

于 2014-03-03T11:56:37.400 回答