Java同步 - 我是否需要这个简单的方法?

时间:2009-06-14 15:36:25

标签: java synchronization methods

我有一个从多个线程调用的简单方法;

@Override
public Bitmap getFullBitmap(Filter f, ProgressCallback<String> pc) {
    // Requires synchronisation?
    Bitmap bitmap = fullMap.get(f.id);
    if(bitmap == null){
        f.setProgressCallback(pc);
        bitmap = f.e.evaluate(currentBitmap);
        fullMap.put(f.id, bitmap);
    }
    return bitmap;
}

因为没有使用的对象是类的字段(除了fullMap),只需调用它或者一个线程可能会改变位图的值,例如,当方法执行时?

fullMap是一个SoftHashMap,它维护索引的Bitmap对象的SoftReferences,但是用于创建它的Filter的id。如果这是有道理的。

我没有遇到任何问题,但我认为我可能需要它。

如果不清楚,请询问澄清,这个问题在我脑海中有意义;)

修改

  • currentBitmap是Bitmap类型的对象,系统中有一个位图被认为是当前的,它由此类管理。
  • 此代码构成一个非常基本的缓存, 返回的位图将永远是 每个id都相同,不是 在此方法之外修改。
  • 在a中使用Soft References SoftHashMap由Dr Heinx描述,FIFO队列为hard 最近的10个参考文献 我希望避免昂贵的电话 评估。话虽如此, 调用f.e.evaluate将返回一个 如果是相同的位图对象 给出相同的输入。过了一些 以为它似乎在同步 这个方法没什么好主意 积极的是两个线程 为此执行此代码 过滤器。
  • 另外我制作了位图最终版 创作后不应该变异。

非常感谢! GAV

6 个答案:

答案 0 :(得分:4)

2个主题可以同时访问地图fullMap。两者都可以确定地图不包含同一个键​​的值,每个都创建一个,然后将其写回,从而插入两次键。

除了效率之外,这可能不是一个问题。然而,它可能会引起混淆,并且随着您的解决方案的发展可能在未来出现问题(将来创建这些对象的成本有多大?如果有人在不合适的地方复制/粘贴代码,会发生什么?)

我强烈建议同步上面的内容(很可能是fullMap本身而不是包含对象,但在确定需要什么之前,更多上下文会有用)

答案 1 :(得分:2)

SoftHashMap.put本身可能不是线程安全的。 SoftHashMap不在标准库中,但WeakHashMap是,并且它未同步。除了在地图上同步方法之外,您可能希望使用Collections.synchronizedMap来确保其他方法不会同时修改地图。

答案 2 :(得分:1)

您绝对需要同步,因为您可以让两个线程决定f.id不在地图中,构造然后添加一个。每个线程都将返回f.id的差异实例,即使该地图仅包含最后完成的那个。

问题不在于变量bitmap。这是线程安全的,因为它是单个线程的本地。但是,访问`fullMap - 我假设是该类的一个字段 - 需要同步,因为你正在做一个“如果没有”的事实。

假设构建位图的成本很高,最好的方法就是同步方法getFullBitmap()。如果它构造起来非常便宜 - 比同步便宜 - 那么我建议总是构建新对象并在putIfAbsent上进行ConcurrentMap。但是当构造对象的代价很​​高时,这是一个坏主意。

答案 3 :(得分:0)

如果你的方法只使用传入的参数和局部变量,没有共享状态,那么我会说它是线程安全的,不需要同步。

线程安全必须担心可变的共享状态。 fullmap是该对象状态的一部分吗?如果是,那么您必须同步其访问权限。

答案 4 :(得分:0)

如果返回的Bitmap在方法之外修改,我会选择同步路径。你冒着2个线程访问上面方法的风险,而f.id上的Bitmap为null,都创建一个并将其添加到地图,第二个覆盖Map中的第一个。现在你有两个,一个将被thread-1修改但是一旦thread-1完成其处理就会超出范围,另一个来自thread-2,它将保留在地图中并提供给所有未来请求者。

答案 5 :(得分:0)

我不确定这一点,但如果你有代码,迭代“fullMap”,AFAIK你可能会被抛出一种“Concurent Modification Exception”。这不能在您的代码中,但可能发生在SoftMap的库例程中。 这可能会导致您的代码在运行时偶尔断开,没有明显的原因,并且没有一个好的方法来处理这种情况。

只是一种复杂的说法:“如有疑问,请小心”。 顺便说一句:不要先考虑当今计算机的性能。

快乐黑客

Huibert Gill