【问题标题】: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


【解决方案1】:
  1. 不鼓励在this 上进行同步,因为如果将对象本身用作外部锁,则会破坏内部同步。另外,请记住synchronized 方法也使用this 作为锁,这可能会导致不良影响。
  2. 建议声明锁final,以防止在synchronized块内重新分配锁对象,从而导致不同线程看到不同的锁对象。看到另一个问题:Locking on a mutable object - Why is it considered a bad practice?

【讨论】:

    【解决方案2】:

    假设您有thread1thread2 访问method1thread3thread4 访问method2 的场景。如果thread1thread2 正在访问method1,则在this 上同步将阻塞thread3thread4,这不应该发生,因为thread3thread4method1 无关。对此的优化是使用两个不同的锁而不是锁定整个类实例。

    这是我在 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
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2016-06-18
          • 2011-11-25
          • 1970-01-01
          • 2019-05-21
          • 2012-02-03
          • 2020-04-14
          • 1970-01-01
          • 2015-08-29
          • 1970-01-01
          相关资源
          最近更新 更多