通过ThreadLocal“传递参数”好吗?

时间:2011-04-18 11:00:53

标签: java oop interface static thread-local

我正在构建一个Java网络库和一个使用它的应用程序。该库包括:

  • 接口PacketSocket,具有发送和接收字节数据包的方法。
  • 它的两个实现,一个通过TCP,一个通过UDP。
  • 一个ObjectConnection类,它构建在PacketSocket之上,处理对象到字节数据包的序列化。

应用程序在UDPPacketSocket之上使用RequestConnection。 UDPPacketSocket实现的独特之处在于它支持指定每个数据包是否应该保证传送。我希望能够在应用程序中使用,但是没有办法通过ObjectConnection和PacketSocket接口。

我当然可以在这些接口中的适用方法中添加一个布尔保证参数,但最后(当将有更多的PacketSocket实现时)必须添加更多特定于某些实现的参数,被别人忽视。

相反,我虽然可以使用UDPPacketSocket的静态线程局部属性来执行此操作,如下所示:

class Application {

  public void sendStuff() {

    // is stored in a ThreadLocal, so this code is still thread-safe
    UDPPacketSocket.setGuaranteed(true);

    try {
       myObjCon.send(...);
    } finally {
       // ... restore old value of guaranteed
    }

  }
}

您如何看待这样的方法?

4 个答案:

答案 0 :(得分:3)

我认为它是一个丑陋的黑客,但有时它只是选项,尤其是如果你通过多层代码“传递”一个值而你无法轻易修改该代码。

如果可以,我会避免它。如果可能的话,更好的选择是拥有以下内容

 myObjCon.sendGuaranteed(...);

答案 1 :(得分:0)

我同意这是一个丑陋的黑客。它会起作用,但你最后会后悔这样做。

我通过使用Properties对象传递各种PacketSocket实现参数来解决这个问题。如果这是不合适的,请为不同类型的PacketSocketParameters定义一个PacketSocket接口,其中包含实现类的层次结构。

答案 2 :(得分:0)

我建议使用某种“性能特征”参数,可能类似于Properties实例。然后,每个impl可以使用他们自己的任意属性(例如,当前impl的“保证”)。请注意,您可以通过使用属性上的对象方法(例如get()而不是getProperty())或使用直接Map实例来避免字符串解析。那么你的值可能是真正的对象(例如布尔值)。

答案 3 :(得分:0)

因为我们知道它是一个UDP,所以我们可以解析层并访问具体的东西

( (UDPSocket)connection.getSocket() ).setGuaranteed(true);