- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在寻找一种编写实例工厂的好方法,它为每个线程创建一个类的实例(换句话说:特定于线程的单例)。
为了清楚起见,让我添加一些示例代码:
首先,一般定义工厂的接口(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()
时,该类都会在其实例映射中查找当前线程,以查看该线程是否已经创建了一个实例。如果没有,它会创建一个新的并记住它。
我发现这种天真的方法有几个问题:
Collections.synchronizedMap
使其线程安全,但我想避免这种情况,因为它意味着到处都有大量同步,这可能会对性能产生重大影响。我正在考虑使用 WeakHashMap
而不是解决第二个问题,因为它允许在 key 不再使用后对其条目进行垃圾收集,但我也遇到了两个潜在的问题:
OpenJDK Source
, 通过 expungeStaleEntries()
释放未使用的 key 每次我调用 get(...)
或 put(...)
时都会启动,并且可能涉及多个同步操作,同样,我想避免性能原因。是否有一个不同的解决方案最好不需要使用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/
我最近购买了《C 编程语言》并尝试了 Ex 1-8这是代码 #include #include #include /* * */ int main() { int nl,nt,nb;
早上好!我有一个变量“var”,可能为 0。我检查该变量是否为空,如果不是,我将该变量保存在 php session 中,然后调用另一个页面。在这个新页面中,我检查我创建的 session 是否为空,
我正在努力完成 Learn Python the Hard Way ex.25,但我无法理解某些事情。这是脚本: def break_words(stuff): """this functio
我是一名优秀的程序员,十分优秀!