代码之家  ›  专栏  ›  技术社区  ›  non sequitor

你能在Java中锁定本地对象吗?

  •  1
  • non sequitor  · 技术社区  · 16 年前

    private Templates retrieveFromCache(String name) {
            TemplatesWrapper t = xlCache.get(name);
            synchronized(t){
                if (!t.isValid()) {
                    xlCache.remove(name);
                    return null;
                }
            }
            return t.getTemplate();
        }
    

    xlCache 是一个 ConcurrentHashMap t NullPointerException 我的假设正确吗?因为我知道并发性是更难推理的事情之一

    这是 private 方法也是从 public 方法,它有区别吗?

    被抛出是不正确的,因为 remove() boolean 使同步变得毫无意义;然而,我的问题是锁定本地对象,这个问题得到了回答。

    5 回复  |  直到 16 年前
        1
  •  2
  •   Jon Skeet    16 年前

    ConcurrentHashMap (以及 Map / ConcurrentMap remove 方法返回a boolean ,表示是否有任何事情 实际上删除。

    参考

        2
  •  2
  •   Kevin    16 年前

    你可以锁定任何你想要的对象。然而,在你的情况下,看起来你可以更清晰、更安全地解决这个问题。

    TemplatesWrapper 从某个未知的位置,任何人都可以在其上同步,这使得控制并发性变得非常困难。仅仅通过查看代码,就应该尽可能清楚地知道为什么某些东西会被锁定。

    最好将同步放在xlCache中,类似于 removeIfInvalid()

        3
  •  1
  •   Gareth Davis    16 年前

    因为你没有检查t是否为空。我猜你刚刚在代码示例中错过了这一点?

        4
  •  1
  •   james    16 年前

    private Templates retrieveFromCache(String name) {
        TemplatesWrapper t = xlCache.get(name);
    
        if (!t.isValid()) {
            xlCache.remove(name, t);
            return null;
        }
        return t.getTemplate();
    }
    
        5
  •  0
  •   Dean J    16 年前

    如果remove(null)会调用空指针异常,这似乎是合理的。如果你不认为冲突是一个常见的问题,你也可以实现一个可能更快的代码版本,只需围绕它包装一个try/catch而不是一个synchronized。

    无论哪种情况,我都会在那里添加一条评论来解释你为什么这样做,这样一个月后,它仍然有意义。