gpt4 book ai didi

java - 盒装原语同步

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:13:59 26 4
gpt4 key购买 nike

我是多线程编程的新手。所以我需要一些帮助来解决这个问题。我在盒装原语上得到一个同步的 findbugs 错误:

http://findbugs.sourceforge.net/bugDescriptions.html#DL_SYNCHRONIZATION_ON_BOXED_PRIMITIVE

我在这个网站上尝试了一些解决方案,但它没有像我预期的那样工作。有时我会从 findbugs 得到类似的错误。

我的代码需要锁定我传递给构造函数的 id,这里是一些伪代码:

public class MyClass{
public MyClass(long id){
synchronized(id){
// do some stuff
}
}
}

问题是,只有具有相同 ID 的线程才应该阻塞在同步块(synchronized block)上。具有不同 ID 的线程应该同时工作。

我也试过类似的方法,但它对我不起作用:

public class MyClass{

private static final ConcurrentHashMap<Long, Object> myHashMap = new ConcurrentHashMap<Long, Object>();

public MyClass(long id){

Object object = getObject(id);

synchronized(object){
// do some stuff
}
}

private Object getObject(long id){
if(!myHashMap.contains(id)){
writeObject(id);
}
return myHashMap.get(id);
}

private synchronized void writeObject(long id){
if(!myHashMap.contains(id)){
myHashMap.put(id, new Object());
}
}
}

在您看到的第二个示例中,我尝试将每个 id 的对象放入 hashmap 中,但是我意识到一个单元测试,具有相同 id 的线程进入同步块(synchronized block)。但他们不应该这样做。如果有人有其他解决方案或如何处理这些问题,我将非常感激。

最佳答案

你写了一个单元测试真是太好了!供将来引用:您想测试所有类型的边缘值,这意味着数字至少为 0、-1、1、MAX_VALUE、MIN_VALUE - 这会发现您错过的第二个错误:-)

您的代码存在的问题是:synchronized(l) {} 转换为:synchronized(Long.valueOf(l)){}valueOf 将 Longs 缓存在 -128、127 范围内,但即使这是可选(令人惊讶的是,JLS 只需要整数!)。因此,一旦您的 ID 大于 127,您的整个方案就会分崩离析。

您的第二种方法是要走的路,但您不能只使该方法同步 - 它只会在 this 上同步,因此不能保证静态映射的原子性。

而是做这样的事情:

Object newLock = new Object();
Object oldLock = map.putIfAbsent(id, newLock);
Object lock = oldLock != null ? oldLock : newLock;
synchronized(lock) {

}

关于java - 盒装原语同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23638792/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com