我多次遇到如下代码
class Foo {
private Object lock = new Object();
public void doSomething() {
synchronized(lock) {
...
我感兴趣的是为什么要创建锁定对象而不是写入synchronized(this)
?是否可以启用共享锁?我依稀记得读过它是一种优化。真的吗?此外,在某些情况下,将锁声明为 是否有意义final
?
我多次遇到如下代码
class Foo {
private Object lock = new Object();
public void doSomething() {
synchronized(lock) {
...
我感兴趣的是为什么要创建锁定对象而不是写入synchronized(this)
?是否可以启用共享锁?我依稀记得读过它是一种优化。真的吗?此外,在某些情况下,将锁声明为 是否有意义final
?
this
因为如果对象本身被用作外部的锁,它会破坏内部同步。另外,请记住,synchronized
方法也this
用作锁,这可能会导致不良影响。final
以防止在synchronized
块内重新分配锁对象的情况,从而导致不同的线程看到不同的锁对象。请参阅另一个问题:锁定可变对象 - 为什么它被认为是一种不好的做法?想象一个场景,您可以访问,thread1
然后访问。同步 on会阻塞,如果或正在访问不应该发生的事情,并且与. 对此的优化是使用两个不同的锁而不是锁定整个类实例。thread2
method1
thread3
thread4
method2
this
thread3
thread4
thread1
thread2
method1
thread3
thread4
method1
这是我在 JavaDoc 上找到的一个很好的段落,它反映了这一点:
同步语句对于通过细粒度同步提高并发性也很有用。例如,假设 MsLunch 类有两个从未一起使用的实例字段 c1 和 c2。这些字段的所有更新都必须同步,但没有理由阻止 c1 的更新与 c2 的更新交错 - 这样做会通过创建不必要的阻塞来降低并发性
考虑使用 java.util.concurrent 包中的锁
这可能会提供更优化的锁定,例如 - 使用ReadWriteLock将使所有读者无需等待即可访问。
这是“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
}
}