此問題是基於Synchronizing on an Integer value。在Integer上同步會導致NullPointerException
那裏的解決方案似乎很好,只有小問題,它沒有解決如何刪除ConcurrentHashMap
中的值的問題。
因此,要解決,我做到了以下程序
import java.util.concurrent.ConcurrentHashMap;
public class Example {
private final ConcurrentHashMap<Integer, Integer> concurrentHashMap = new ConcurrentHashMap<Integer, Integer>();
public void doSomething(int i) {
synchronized (getLockForId(i)) {
concurrentHashMap.remove(i);
}
}
public Integer getLockForId(int id) {
concurrentHashMap.putIfAbsent(id, id); // I want to replace these two
// operation with single one
// since it seems the cause of
// NPE
return concurrentHashMap.get(id);
}
public static void main(String[] args) {
final Example example = new Example();
new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while (true) {
example.doSomething(++i);
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while (true) {
example.doSomething(++i);
}
}
}).start();
}
}
問題是,它總是導致NullPointerException
。我的第一個分析是因爲我刪除了它被賦值爲空的值,所以它導致了NullPointerException
。所以,我沒有下文
Object obj = new Object();
synchronized (obj) {
obj = null;
}
但上面並沒有導致NullPointerException
。所以我的問題是爲什麼它在上面的情況下拋出NullPointerException
?
即使我做
public Integer getLockForId(int id) {
return concurrentHashMap.putIfAbsent(id, id);
}
仍然導致NullPointerException
,因爲它只返回值時,有其他人返回null
這個問題基於整數*對象*不是值的同步。 – Aubin
爲什麼在完成後需要從地圖中刪除值? –
@NikitaBeloglazov最終必須有一點,那些需要被刪除的權利?它需要同步的問題。那麼我看不到其他解決方案。 –