我有一个多线程应用程序,运行良好。但是它正在遇到锁竞争问题(通过快照Java堆栈并查看等待的对象来检查)。
每个线程从列表中消耗对象,然后拒绝每个对象或将其放入Bin中。
由于每个Bin可能很昂贵(而且可能会有很多),因此最初它们为空。
导致争用的代码大致如下:
每个线程从列表中消耗对象,然后拒绝每个对象或将其放入Bin中。
由于每个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);
}
}
瓶颈在于对bins
数组的同步。
我的同事建议我使用双重检查锁定来解决这个问题,但我们不确定需要哪些步骤才能确保安全。建议的解决方案如下:
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);
}
}
这样做安全吗?是否有更好/更安全/更符合惯用法的方法?