在Java中同时使用线程和Flyweight模式?
我对多线程和使用设计模式都是新手 我有一些线程使用显式多线程,假设每个线程都计算一个数字的阶乘,如果它从来没有被任何线程计算过。我用的是Flyweight图案在Java中同时使用线程和Flyweight模式?,java,multithreading,flyweight-pattern,Java,Multithreading,Flyweight Pattern,我对多线程和使用设计模式都是新手 我有一些线程使用显式多线程,假设每个线程都计算一个数字的阶乘,如果它从来没有被任何线程计算过。我用的是Flyweight图案 private final long Comp; private static Map<String, Fact> instances=new HashMap<String, Fact>(); private Fact(long comp) { Comp=comp;
private final long Comp;
private static Map<String, Fact> instances=new HashMap<String, Fact>();
private Fact(long comp) {
Comp=comp;
}
public static Fact getInstance(int num){
String key=String.valueOf(num);
if(!instances.containsKey(key)){
int comp=//calculate factorial of num
instances.put(key, new Fact(comp));
}
return instances.get(key);
}
public long get_Comp(){
return this.Comp;
}
}
如果我这样做了,那么说我的线程是计算阶乘是对的吗
如果我添加了计算事实(Flyweight)类,那么它是否仍然是Flyweight,我想是的
我也非常感谢任何其他我希望的方法。这里有几个目标。做什么取决于你想做什么 因此,在这种情况下,您似乎试图避免重复计算,但这种计算并不特别昂贵。您可能会遇到锁争用问题。因此,要使其线程安全,请使用
ThreadLocal
。可能InheritableThreadLocal
其中childValue
复制Map
通常,有一组已知的值可能很常见,而您只需要这些值。在这种情况下,在类静态初始化期间计算映射(或数组)
如果希望flyweights在线程之间共享且唯一,请使用ConcurrentHashMap
和Map.computeIfAbsent
方法
如果希望flyweights在线程之间共享,请保持唯一性,并确保只执行一次计算,这会变得有点困难。您需要在ConcurrentMap
中放置(如果没有)占位符;如果当前线程获胜,则将其替换为计算值并通知,否则等待计算
现在,如果希望对飞锤进行垃圾收集,则需要WeakHashMap
。这不能是使用JavaSE集合的ConcurrentMap
,这让它有点绝望。你可以用老式的锁。或者,该值可以是WeakReference
,但您需要自己管理逐出
可能是对事实的强引用只是间歇性地保留,但您不希望太频繁地重新创建,在这种情况下,您将需要软引用
,而不是软引用
。事实上,WeakHashMap
可以表现出出乎意料的,在某些情况下会导致性能在之前正常工作后下降到无法使用的
(注意,在这种情况下,映射
最好键入整数
)哈希映射
不是线程安全的。对于来自多个线程的访问,请考虑<代码> CONCURNESHASMAP 。然后还可以使用computeIfAbsent
功能。为什么要把钥匙变成字符串
?您也可以使用Integer
。对于long
来说,阶乘也会很快变得太大。谢谢@Thilo,我会记住这一点
public class Th implements Runnable {
// code elited
@Override
public void run() {
//get number and check if it's already in the HashMap, if no,
compute
}
}