我想使我的类线程安全,而不需要大量开销。这些实例很少同时使用,但可能会发生。类的大多数是不可变的,只有一个可变成员用作缓存:
private volatile SoftReference<Map<String, Something>> cache
= new SoftReference(null);在构造函数(非共享)中分配的
Map<String, Something> tmp = new HashMap<String, Something>();
tmp.put("a", new Something("a");
tmp.put("b", new Something("b");
cache = new SoftReference(tmp);赋值之后,地图就不会被修改。
如果两个线程并行计算缓存,这是没有问题的,因为值将是相同的。“做两次”这个词的额外开销是可以接受的。
当一个线程看不到由另一个线程计算出来的值时,它就没有必要计算它,这是可以接受的。这是不可能的,因为不稳定。当一个线程看到由另一个线程计算的值时,它就没问题了。
唯一可能的问题是线程看到不一致的状态(例如,部分填充的映射)。这会发生吗?
备注:
发布于 2011-02-07 19:16:05
唯一可能的问题是线程看到不一致的状态(例如,部分填充的映射)。这会发生吗?
不是的。在线程中执行的操作必须按照顺序执行。写入易失性变量会发生--在读取该值之前。因此,在任何线程从字段读取对映射的引用之前,都会对映射进行初始化。
发布于 2011-02-07 19:59:05
使用软引用的问题是,在GC之后,可能会丢失整个映射/缓存。这意味着应用程序的性能可能会受到很大的影响。最好使用带有驱逐策略的缓存,这样您就不会遇到这个问题。
挥发性物质不能保证任何行动的安全。
您还没有展示所有的代码,也许我们可以就如何改进代码提供一些建议,例如您的示例代码应该编译;)
https://stackoverflow.com/questions/4925387
复制相似问题