gpt4 book ai didi

java - 每线程单例模式

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:15:33 24 4
gpt4 key购买 nike

在我的工作中我偶然发现了这样一个设计问题:

  • 我需要每个线程一个 Manager 类的实例
  • 这些实例应该是全局可访问的,就像通过静态函数在单例模式中一样
  • 每个线程可能需要用不同的参数初始化它的实例
  • 这些实例的生命周期应该是可控的,有时删除一个实例并让 GC 收集它是有益的

如果存在这种情况,前两点将使它成为“每线程单例”。

这是我想出的(代码已简化,我省略了安全检查等):

public class Manager {
private final static ThreadLocal<Manager> local = new ThreadLocal<Manager>();

private int x;
Manager(int argument) { x = argument; }

public static void start(int argument) { local.set(new Manager(argument); }
public static void clean() { local.remove(); }

private void doSomething1() { x++; .... }
private int doSomething2() { if (--x == 0) clean(); ... }

public static void function1() { local.get().doSomething1(); }
public static int function2() { return local.get().doSomething2(); }
}

如您所见,还可以从私有(private)方法中调用 clean 函数。另请注意,通过使用静态函数,对实例的引用永远不会泄漏,因此分配给不同线程的实例不会混合。

这工作得很好,但后来我有另一个要求:

  • 不同线程可能需要使用Manager类的不同实现

所以我定义了一个接口(interface):

public interface ManagerHandler {
void method1();
int method2();
}

并修改了Manager类:

public class Manager {
private final static ThreadLocal<ManagerHandler> local = new ThreadLocal<ManagerHandler>();

public static void start(int argument) {
ManagerHandler handler;
// depending on the context initialize handler to whatever class it is necessary
local.set(handler);
}
public static void clean() { local.remove(); }

public static void function1() { local.get().method1(); }
public static int function2() { return local.get().method2(); }
}

一个示例实现如下所示:

public class ExampleManagerImplementation implements ManagerHandler {
private int x;
public ExampleManagerImplementation(int argument) { x = argument; }
public void method1() { x++; .... }
public int method2() { if (--x == 0) Manager.clean(); ... }
}

Manager 类在这里用作外观,将所有调用转发给适当的处理程序。这种方法有一个大问题:我需要在 Manager 类和 ManagerHandler 接口(interface)中定义所有函数。不幸的是 Manager 类不能实现 ManagerHandler 接口(interface),因为它有静态函数而不是方法。

问题是:您能想出一种更好/更简单的方法来实现我上面列出的所有目标,并且不会出现这个问题吗?

最佳答案

你能做的不多,因为你基本上需要通过静态方法来代理接口(interface)方法。我只能想到两种不同的方式来实现相同的功能:

  1. 如果您使用的是 DI 框架,您可以摆脱静态 Manager 并使用 ManagerHandler 的注入(inject)实现,它将包含 ThreadLocal
  2. 使用 ManagerHandler 接口(interface)中的方法生成(如“字节码生成”)静态 ManagerAccess 类。

就我个人而言,我不认为静态 ManagerAccess 类(包含 ThreadLocal)是一个严重的设计问题。至少只要它坚持自己的职责集(访问线程范围的实例和代理调用)并且不会在其他任何地方冒险。

关于java - 每线程单例模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7360172/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com