繁体   English   中英

是否有必要在可能由单个线程调度程序修改的字段上使用Java同步?

[英]Is it necessary to use Java synchronization on a field that might be modified by a single thread scheduler?

我有一个课程(外语课),以下内容

  1. 包含数据的List字段

  2. List字段的getter方法

  3. getDataFromDB方法从在线数据库返回List

  4. 一个实现Runnable的内部类,并在其run方法中修改List字段

  5. 在outter类的initialize方法中,将设置一个SingleThreadScheduledExecutor,它将调度内部类运行

我想知道是否有必要将同步块放在哪里

  1. 在getter方法中读取List字段(2)

  2. List字段在内部类的run方法中被修改(这是一个Runnable,将由SingleThreadScheduledExecutor调度)(4)

public class OutterClass{

  private List<Data> data;
  private ScheduledExecutorService scheduledExecutorService;

  @PostConstruct
  private void initialize(){
    scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
    scheduledExecutorService.scheduleWithFixedDelay(new InnerClass(), // other configs);
  }

  private List<Data> getDataFromOnlineDB() {/* some work */}

  public synchronized List<Data> getData() { return data; }

  private class InnerClass implements Runnable {
    @Override
    public void run() {
      synchronized (OutterClass.this) {
        data = getDataFromOnlineDB();
      }
    }
  }
}

要回答您的问题,我们需要知道托管数据的预期访问模式。

如上所述,您的代码处理访问模式,其中在构造对象之后的某个时间点分配托管数据,并且可以在构造对象之后的任何时间点访问托管数据,其中分配发生在一个线程和访问从其他线程发生。 这是您打算支持的访问模式吗?

这是一个小的更新,以帮助清理代码。 唯一的区别是句法重排。 功能完全一样。

需要注意的主要更新是“数据”的赋值是在setter中进行的。 这使得同步更加清晰。

public class OuterClass {

  // Some data to be managed.  Centralize all explicit references.
  private List<Data> data;
  public synchronized List<Data> getData() { return data; }
  public synchronized void setData(List<Data> data) { this.data = data; }

  // An executor used to launch code which asynchronously
  // compute and assigns the managed data.
  private ScheduledExecutorService scheduledExecutorService;

  // Tie into this instance lifecycle by launching
  // a thread that computes and assigns managed data.
  @PostConstruct
  private void initialize(){
    scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
    scheduledExecutorService.scheduleWithFixedDelay(new InnerClass(), // other configs);
  }

  // Code which computes the data ...
  private List<Data> getDataFromOnlineDB() {/* some work */}

  // A runnable used to asynchronously compute and assign the managed data.
  private class InnerClass implements Runnable {
    @Override
    public void run() {
        setData( getDataFromOnlineDB() );
    }
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM