我有一个应用程序是多线程和工作正常.然而,它遇到了锁争用问题(通过快照查看
java堆栈并查看等待的内容).
每个线程都从列表中消除对象,并拒绝每个线程或将其放入Bin.
箱子最初是空的,因为每个都可以是昂贵的(并且有可能很多它们).
导致争用的代码大致如下:
public void addToBin(Bin[] bins,Item item) {
Bin bin;
int bin_index = item.bin_index
synchronized(bins) {
bin = bins[bin_index];
if(bin==null) {
bin = new Bin();
bins[bin_index] = bin;
}
}
synchronized(bin) {
bin.add(item);
}
}
它是在瓶颈阵列上的同步,这是瓶颈.
有一位同事向我建议使用双重锁定来解决这个问题,但是我们不确定它会涉及什么来使其安全.建议的解决方案如下所示:
public void addToBin(Bin[] bins,Item item) {
int bin_index = item.bin_index
Bin bin = bins[bin_index];
if(bin==null) {
synchronized(bins) {
bin = bins[bin_index];
if(bin==null) {
bin = new Bin();
bins[bin_index] = bin;
}
}
}
synchronized(bin) {
bin.add(item);
}
}
这是安全的还是/或者有更好/更安全/更惯用的方式来做到这一点吗?