Java ThreadLocal与参数传递-在接口设计中选择什么?

Java ThreadLocal与参数传递-在接口设计中选择什么?,java,interface,thread-local,Java,Interface,Thread Local,我已经阅读了关于以下关于ThreadLocal及其使用的SO线程的有趣讨论 这个问题更多的是设计时的选择。我的情景是这样的 如果我在web应用程序中有一个几乎所有步骤都需要在同一线程中使用的值对象。我可以想到如下两种界面设计选项 使用方法参数传递接近#1 到目前为止,我的重点是提出一个接口,该接口可以包含带有值对象接口参数的方法 例如: public interface SomeDataProcessorInterface { public void processSomethin

我已经阅读了关于以下关于ThreadLocal及其使用的SO线程的有趣讨论

这个问题更多的是设计时的选择。我的情景是这样的

如果我在web应用程序中有一个几乎所有步骤都需要在同一线程中使用的值对象。我可以想到如下两种界面设计选项

使用方法参数传递接近#1

到目前为止,我的重点是提出一个接口,该接口可以包含带有值对象接口参数的方法

例如:

public interface SomeDataProcessorInterface {

public void processSomething(SomeValueObjectInterface vo);

}

public interface SomeValueObjectInterface extends Serializable {}
Aproach#2使用ThreadLocal

在这种方法中,我可以拥有一个没有方法参数的接口,只需创建一个静态类,使用threadlocal访问我的值对象

例如:

public interface SomeDataProcessorInterface {

public void processSomething();

}

public interface SomeValueObjectInterface extends Serializable {}

public Class StaticClass {

    private static ThreadLocal<SomeValueObjectInterface> threadLocalVO = new ThreadLocal<SomeValueObjectInterface>();

     public static ThreadLocal getThreadLocal() {
        return threadLocal;
      }
公共接口SomeDataProcessor接口{
公共空间(某物);
}
公共接口SomeValueObjectInterface扩展了可序列化{}
公共类静态类{
私有静态ThreadLocal threadLocalVO=new ThreadLocal();
公共静态ThreadLocal getThreadLocal(){
返回本地;
}
哪种方法更好?为什么?

以下哪种实现的内存泄漏几率较小?

以下哪种实现对Java垃圾收集器有好处?


我阅读了其他线程中的一些要点,但我仍然不清楚如果我从头开始,哪种方法更好。

使用
静态
数据局部
如果忘记删除元素,则可能会导致内存泄漏。在从方法返回之前,您总是可以通过删除元素来避免这种情况。我不会建议采用这种方法


目前,您的第一种方法已经是线程安全的,因为参数将仅在该方法调用的本地。请使用此方法。

这是一个设计问题,取决于您的情况

如果代码> SoeMealObjultObjult界面<代码>在服务的业务逻辑上下文中有意义,那么(我相信)它应该是一个参数,但是如果你把它当作横切关注点的数据(不是作为方面实现的方面),并且它不是业务逻辑的参数,那么使用<代码> thRead本地< /代码> .< 顺便说一句,不要忘记在

finally
块中清除
ThreadLocal
,否则会遇到内存泄漏问题(通常很难找到)


GC没有区别,因为如果你没有忘记清除
ThreadLocal
,那么这两种方法中的对象都会在eden中。

如果你可以选择将某个对象作为方法参数传递还是通过ThreadLocal存储,你应该99.99999%的时间将其作为方法参数传递EADStand存储是处理一个间接调用一个方法的实例(意思是一个请求其他方法反过来调用感兴趣的方法),一个需要传递信息到内部方法,中间的方法不提供传递该信息的方便管道。如果没有中间层。,可以简单地将附加参数添加到内部方法的签名中(通常,内部方法只能由包含信息的代码调用,因此在方法定义和调用站点添加参数应该没有问题)。但是,在某些情况下,存在中间层,必须使用中间层

对于样例,考虑一个<代码> SpuleCopEngs<代码>,其中包含一个<代码> DrawAll < /C> >方法,该方法在所有形状上调用<代码>绘制< /代码>。应用程序定义了一些不好渲染的形状。,从而在每个窗口中添加一个选项,以选择是否将此类形状显示为占位符而不是详细的渲染。如果

形状
的设计考虑了此类需求,则其
绘制
方法可能包括
asPlaceHolder
参数和
形状集合
绘制所有
可以接受这样一个参数并将其传递给每个形状。但是,如果
shape
的设计者没有预料到这种需要,
ShapeCollection
将不支持它


如果每个奇特形状对象的
Draw
方法仅用于更新一个特定窗口,则形状可以保留对该窗口的引用,并使用该窗口的“使用占位符”选项来确定如何渲染自身。但是,如果可能有多个窗口显示形状视图,并且每个窗口都应支持自己的渲染选项,则该方法可能不起作用。如果使用
Draw
方法为剪贴板、打印机或其他媒体渲染内容,则这种方法也可能会出现问题m、 让一个窗口的绘图代码构造一个
DrawingOptions
对象,创建一个对它的线程本地引用,调用
DrawAll
,然后删除该线程本地引用将是不雅观的,但它将为调用
drawingoll
提供一种方法,将绘图选项传递给内部
Draw
方法否则这是不可能的。

请求参数有什么问题吗?我假设值绑定到请求,而不是
线程
。我个人喜欢请求参数,并且已经使用了很长时间。我见过一些框架使用ThreadLocal方法跨线程共享用户对象。更像是线程级别全局变量。我之所以喜欢它,是因为如果我以后必须使用一个以上的参数,我的接口不会改变。我可以只添加一个以上的线程局部变量,并在需要更改时继续执行相同的操作。参数传递的一个缺点是,我需要将相同的值对象传递给应用程序中的所有处理器