gpt4 book ai didi

java - 特定于线程的单例实例

转载 作者:行者123 更新时间:2023-11-30 07:07:44 26 4
gpt4 key购买 nike

我正在寻找一种编写实例工厂的好方法,它为每个线程创建一个类的实例(换句话说:特定于线程的单例)。

为了清楚起见,让我添加一些示例代码:

首先,一般定义工厂的接口(interface):

public interface Factory<T> {
public T create();
}

对于普通的单例,我可以创建一个包装另一个工厂的这个接口(interface)的实现:

public class SingletonFactory<T> implements Factory<T> {

private final Factory<T> factory;
private T instance = null;

public SingletonFactory(Factory<T> factory) {
this.factory = factory;
}

@Override
public T create() {
if (instance==null) instance = factory.create();
return instance;
}
}

基本上,第一次调用 create() 时,此调用将转发到提供的工厂以创建对象的一个​​实例。此实例已缓存,以后所有对 create() 的调用都将返回同一实例。我需要做的就是确保每个对象类型 T 周围只有一个 SingletonFactory 实例。

假设我想为每个线程提供对象的一个​​实例:我可以这样做:

public class ThreadSingletonFactory<T> implements Factory<T> {

private final Factory<T> factory;
private final Map<Thread, T> instance;

public ThreadSingletonFactory(Factory<T> factory) {
this.factory = factory;
this.instance = new HashMap<Thread, T>();
}

@Override
public T create() {
Thread thread = Thread.currentThread();
T result = instance.get(thread);
if (result==null) {
result = factory.create();
instance.put(thread, result);
}
return result;
}
}

现在,每次调用 create() 时,该类都会在其实例映射中查找当前线程,以查看该线程是否已经创建了一个实例。如果没有,它会创建一个新的并记住它。

我发现这种天真的方法有几个问题:

  1. HashMap 不是线程安全的,这可能不是问题,因为没有两个线程会操作同一个键,但我不确定。我可以使用 Collections.synchronizedMap使其线程安全,但我想避免这种情况,因为它意味着到处都有大量同步,这可能会对性能产生重大影响。
  2. 如果应用程序不使用线程池,而是不断产生成吨又成吨的短生命周期新线程,则映射将增长到潜在的巨大尺寸并阻塞大量内存,不再需要实例。

我正在考虑使用 WeakHashMap而不是解决第二个问题,因为它允许在 key 不再使用后对其条目进行垃圾收集,但我也遇到了两个潜在的问题:

  1. 查看 OpenJDK Source , 通过 expungeStaleEntries() 释放未使用的 key 每次我调用 get(...)put(...) 时都会启动,并且可能涉及多个同步操作,同样,我想避免性能原因。
  2. 我仍然不确定是否还需要将 map 包装到 synchronizedMap 中以确保不会遇到并发问题。

是否有一个不同的解决方案最好不需要使用any同步(假设Factory.create()的所有实现都是线程安全)?如果它确实需要以某种方式管理并发,我更希望它通过 java.util.concurrent.atomic 中的类来实现。 .

最佳答案

根据@JBNizet 和@SotiriosDelimanolis 的建议,ThreadLocal可能会成功。

我还没有测试过,但可能就是这样?

public class ThreadSingletonFactory<T> implements Factory<T> {

private final ThreadLocal<T> instance;

public ThreadSingletonFactory(final Factory<T> factory) {
this.instance = new ThreadLocal<T>() {
@Override
protected T initialValue() {
return factory.create();
}
};
}

@Override
public T create() {
return instance.get();
}
}

关于java - 特定于线程的单例实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24599136/

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