如何重构基于字符串的同步块
How to refactor a synchronization block based on string
我正在重构一个遗留项目,我发现了一个使用 String
进行同步的代码(实际上它是一个缓存实现)。
public void method (String key, ...) {
synchronized(key) {
....
}
}
只有一个块在 String 对象上同步 key
。
我想知道 fixing/Refactoring 代码的最佳方式是什么?
有什么想法吗?
一种方法是采用以下模式:
private final ConcurrentHashMap<String, Object> lockMap = new ConcurrentHashMap<>();
public void method(String key, ...) {
synchronized(getLock(key)) {
....
}
}
protected Object getLock(String key) {
Object newLock = new Object(), lock = lockMap.putIfAbsent(key, newLock);
return lock == null? newLock: lock;
}
请注意,这是一个经过验证的模式,因为 Java 7 引入的并行 class 加载程序也使用它。
使用Java 8,可以简化代码:
protected Object getLock(String key) {
return lockMap.computeIfAbsent(key, x->new Object());
}
我正在重构一个遗留项目,我发现了一个使用 String
进行同步的代码(实际上它是一个缓存实现)。
public void method (String key, ...) {
synchronized(key) {
....
}
}
只有一个块在 String 对象上同步 key
。
我想知道 fixing/Refactoring 代码的最佳方式是什么?
有什么想法吗?
一种方法是采用以下模式:
private final ConcurrentHashMap<String, Object> lockMap = new ConcurrentHashMap<>();
public void method(String key, ...) {
synchronized(getLock(key)) {
....
}
}
protected Object getLock(String key) {
Object newLock = new Object(), lock = lockMap.putIfAbsent(key, newLock);
return lock == null? newLock: lock;
}
请注意,这是一个经过验证的模式,因为 Java 7 引入的并行 class 加载程序也使用它。
使用Java 8,可以简化代码:
protected Object getLock(String key) {
return lockMap.computeIfAbsent(key, x->new Object());
}