通过 ReadWriteLock 或 synchronize(this) 锁定会阻塞渲染线程吗?

Would locking via ReadWriteLock or synchronize(this) block a rendering thread?

通过 ReadWriteLock 或 synchronize(this) 锁定会阻塞渲染线程吗?

我正在加载程序之间编写一个适配器,我无法更改代码,例如;

class LoaderAdapter implements Loader {

 private AnotherLoader.Callback callback = new AnotherLoader.Callback() {
   // Called on render thread
   public void onLoaded(Data data) {
     if (mData.equals(data)) {
       return;
     }

     mData = data;

     notifyListeners();
   }
 };

 private final AnotherLoader loader = ...

 private Data mData;

 // Called on render thread
 @Override
 public start() {
  loader.start();
 }


 // Called on background thread
 @Override
 public List<Items> getContent() {
   //iterate over contents
   return processor.process(mData);
 }
}

我认为这不是线程安全的,因为 mData 是在渲染线程上写入的,但读取是从后台线程进行的。

为了解决这个问题,我添加了一个 ReadWriteLock;

class LoaderAdapter implements Loader {

 private AnotherLoader.Callback callback = new AnotherLoader.Callback() {
   // Called on render thread
   public void onLoaded(Data data) {
     lock.writeLock().lock();
     
     try {
       mData = data;
     } finally {
      lock.writelock().unlock();
     }
   }
 };

 private final AnotherLoader loader = ...
 private final ReentrantReadWriteLock lock ....

 private Data mData;

 // Called on render thread
 @Override
 public start() {
  loader.start();
 }


 // Called on background thread
 @Override
 public List<Items> getContent() {
     lock.readLock().lock();
     
     try {
       return processor.process(mData);
     } finally {
      lock.readLock().unlock();
     }
 }
}

现在的问题是在渲染线程上调用了 onLoaded(),而我将调用 .lock()。这会阻塞渲染线程并可能降低渲染速度吗?

有没有办法处理这个问题,同时在两者之间工作类我不能改变?我想到的一个选择是 运行 BG 线程上的 onLoaded() 的内容,以避免在渲染线程上锁定。但是我想知道是否有更优雅的方法来做到这一点。

是的,这会阻塞渲染线程,因为只有在没有持有读锁的情况下才能获取写锁。

在这种情况下使用锁就有点过分了。解决方案是声明 mData volatile:

private volatile Data mData;