如何优化Java中的同步方法

如何优化Java中的同步方法,java,concurrency,synchronized,Java,Concurrency,Synchronized,我在应用程序中看到了这段遗留代码,它导致生产中synchronized方法上的线程被阻塞 private synchronized void productMapBuilder(List<Product> products) { Map<String, Set<Product>> map = new HashMap<>(); for (Product product : products) {

我在应用程序中看到了这段遗留代码,它导致生产中
synchronized
方法上的线程被阻塞

private synchronized void productMapBuilder(List<Product> products) {
        Map<String, Set<Product>> map = new HashMap<>();
        for (Product product : products) {
            map.putAll(buildProductMap(product));// this call another method which isn't synchronised.
        }
        this.productsMap = map;
    }
私有同步void productMapBuilder(列出产品){
Map Map=newhashmap();
用于(产品:产品){
putAll(buildProductMap(product));//此调用另一个未同步的方法。
}
this.productsMap=map;
}
现在,当
列表产品
被传递到这个
产品映射生成器
时,我知道它是一个特定于线程的变量,线程之间唯一共享的变量是
产品映射

那么我们真的需要在整个方法中加入
synchronized


此外,我想不出任何其他方法来优化此方法,因为我不是并发程序方面的专家,因此欢迎提供任何有价值的资源和建议:)

因为
productsMap
是一个实例级变量,这就是此方法被同步的原因。假设
buildProductMap
只是一个实用程序类,不需要同步,那么您在
productMapBuilder
上看到线程被阻塞(而不是死锁)的一个原因可能是
products
是一个巨大的列表,处理它需要时间。当多个线程碰到这段代码时,对象级锁的争用率很高。低争用同步成本很低,但它在高争用中开始产生问题。顺便问一下,您是否分析了线程转储,以确定此方法是否是真正的原因?另外,
productsMap
是方法级变量,因此不需要同步,这是因为
this.productsMap=productsMap
。然而,我有一个问题-您将productsMap分配给实例级变量(因此需要同步)的原因是您将重用它(而不是重新计算)。这是一次性初始化还是每次用户请求都会发生这种情况

Map productsMap=newhashmap()不在线程之间共享。调用此方法时始终会创建它。如果跨线程共享productsMap,则可以尝试使用ConcurrentHashMap,但从代码段看,它似乎不是共享的。另外,如果buildProductMap是线程安全的,则可以在同步范围外重构。@VikramSingh,很抱歉造成混淆,但是如果您注意到它被分配给了同名变量this.productsMap==productsMap
,当我提到shared时,我指的是this.productsMap重命名了变量名以避免混淆。这是否可以更改取决于更多的代码而不仅仅是这个。是否有其他方法在同一个锁上同步?
这个.productsMap是如何使用的?Etc没有回答这个问题,包含了与“类级别变量”(它是一个实例变量)和锁争用无关的内容。“类级别变量”是我已经纠正的打字错误,我确实在下面提到了“实例级别”。