假设我有一个临时集合 (ConcurrentHashMap) 来保存某个对象的引用,例如 HttpSession。当至少一个线程正在使用会话时(在请求的时刻),它不能被删除。但是,当没有更多线程同时使用会话时,应该将其删除以释放内存。我尝试实现一个类似的例子,但我得到了一个 NullPointerException。我做错了什么?:(
class Elem {
// AtomicInteger saldo = new AtomicInteger(1000);
Integer saldo = 1000;
}
class Sum implements Runnable {
Map<String, Elem> saldos;
AtomicInteger n;
public Sum(Map<String, Elem> saldos, AtomicInteger n) {
this.saldos = saldos;
this.n = n;
}
@Override
public void run() {
Random rand = new Random();
int r = rand.nextInt(1000);
Elem e = this.saldos.get("saldo");
//Null Pointer Exception occurs here!
synchronized (e) {
this.n.incrementAndGet();
if (r % 2 == 0) {
Integer saldoLido = e.saldo;
e.saldo += r;
Integer saldoAtual = e.saldo;
System.out.println("saldo lido: " + saldoLido + " somado: " + r
+ " saldo atual: " + (saldoAtual) + " "
+ System.currentTimeMillis());
} else {
Integer saldoLido = e.saldo;
e.saldo -= r;
Integer saldoAtual = e.saldo;
System.out.println("saldo lido: " + saldoLido + " subtraído: "
+ r + " saldo atual: " + (saldoAtual) + " "
+ System.currentTimeMillis());
}
if(this.n.decrementAndGet() == 0)
this.saldos.remove("saldo");
}
}
}
public class Main {
public static void main(String[] args) throws Exception {
Map<String, Elem> saldos = new ConcurrentHashMap<>(20, 0.9f, 1);
AtomicInteger n = new AtomicInteger(0);
saldos.put("saldo", new Elem());
ExecutorService exec = Executors.newFixedThreadPool(20);
try {
for (int i = 0; i < 20; ++i)
exec.execute(new Sum(saldos, n));
exec.shutdown();
while (!exec.isTerminated()) {}
System.out.println("got elem: " + saldos.get("saldo") + " " + n);
} catch (Exception ex) {
exec.shutdownNow();
ex.printStackTrace();
}
}
}