This question is based on Synchronizing on an Integer value.
The solution there seems excellent only there is small problem it does not address the concern how to delete values from ConcurrentHashMap
.
So to address that I did below program
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();
}
}
Problem is that it always results in NullPointerException
. My first analysis was because I am deleting the value it gets assigned to null so it is causing NullPointerException
. So I did below
Object obj = new Object();
synchronized (obj) {
obj = null;
}
But above does not result in NullPointerException
. So My question is why it is throwing NullPointerException
in above case?
Even if I do
public Integer getLockForId(int id) {
return concurrentHashMap.putIfAbsent(id, id);
}
It still results in NullPointerException
because it only returns value when there is one else return null