13

我多次遇到如下代码

class Foo {
   private Object lock = new Object();

   public void doSomething() {
      synchronized(lock) {
         ...

我感兴趣的是为什么要创建锁定对象而不是写入synchronized(this)?是否可以启用共享锁?我依稀记得读过它是一种优化。真的吗?此外,在某些情况下,将锁声明为 是否有意义final

4

4 回答 4

24
  1. 不鼓励同步,this因为如果对象本身被用作外部的锁,它会破坏内部同步。另外,请记住,synchronized方法也this用作锁,这可能会导致不良影响。
  2. 建议声明锁final以防止在synchronized块内重新分配锁对象的情况,从而导致不同的线程看到不同的锁对象。请参阅另一个问题:锁定可变对象 - 为什么它被认为是一种不好的做法?
于 2012-06-30T15:39:15.157 回答
4

想象一个场景,您可以访问,thread1然后访问。同步 on会阻塞,如果或正在访问不应该发生的事情,并且与. 对此的优化是使用两个不同的锁而不是锁定整个类实例。thread2method1thread3thread4method2thisthread3thread4thread1thread2method1thread3thread4method1

这是我在 JavaDoc 上找到的一个很好的段落,它反映了这一点:

同步语句对于通过细粒度同步提高并发性也很有用。例如,假设 MsLunch 类有两个从未一起使用的实例字段 c1 和 c2。这些字段的所有更新都必须同步,但没有理由阻止 c1 的更新与 c2 的更新交错 - 这样做会通过创建不必要的阻塞来降低并发性

于 2012-06-30T16:01:13.157 回答
0

考虑使用 java.util.concurrent 包中的锁
这可能会提供更优化的锁定,例如 - 使用ReadWriteLock将使所有读者无需等待即可访问。

于 2012-06-30T17:08:19.330 回答
0

这是“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
    }
}
于 2012-07-01T01:55:08.033 回答