【问题标题】:Synchronized with a dummy object instead of this与虚拟对象而不是 this 同步
【发布时间】:2012-07-01 18:53:51
【问题描述】:
我已经多次遇到类似以下的代码
class Foo {
private Object lock = new Object();
public void doSomething() {
synchronized(lock) {
...
我感兴趣的是为什么要创建一个锁对象而不是写synchronized(this)?是否可以启用共享锁?我依稀记得读过它是一种优化。真的吗?另外,在某些情况下,将锁声明为final 是否有意义?
【问题讨论】:
标签:
java
multithreading
synchronized
【解决方案2】:
假设您有thread1 和thread2 访问method1、thread3 和thread4 访问method2 的场景。如果thread1 或thread2 正在访问method1,则在this 上同步将阻塞thread3 和thread4,这不应该发生,因为thread3 和thread4 与method1 无关。对此的优化是使用两个不同的锁而不是锁定整个类实例。
这是我在 JavaDoc 上找到的一个很好的段落,它反映了这一点:
同步语句对于提高并发性也很有用
细粒度同步。例如,假设 MsLunch 类有
从未一起使用的两个实例字段 c1 和 c2。全部
这些字段的更新必须同步,但没有理由
防止 c1 的更新与 c2 的更新交错 -
这样做会通过创建不必要的阻塞来降低并发性
【解决方案3】:
考虑使用 java.util.concurrent 包中的锁
这可能会提供更优化的锁定,例如 - 使用 ReadWriteLock 将使所有读者无需等待即可访问。
【解决方案4】:
这是“ReentrantReadWriteLock”的完整工作示例。
public class DataReader {
private static final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private static final Lock read = readWriteLock.readLock();
private static final Lock write = readWriteLock.writeLock();
public static void loadData() {
try {
write.lock();
loadDataFromTheDB());
} finally {
write.unlock();
}
}
public static boolean readData() {
try {
read.lock();
readData();
} finally {
read.unlock();
}
}
public static List loadDataFromTheDB() {
List list = new ArrayList();
return list;
}
public static void readData() throws DataServicesException {
//Write reading logic
}
}