gpt4 book ai didi

java - 是否有必要对可能被单线程调度程序修改的字段使用 Java 同步?

转载 作者:行者123 更新时间:2023-12-02 06:20:32 25 4
gpt4 key购买 nike

我有一个类(class)(外部类(class)),内容如下

  1. 包含数据的列表字段

  2. 列表字段的 getter 方法

  3. 从在线数据库返回列表的 getDataFromDB 方法

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

  5. 在外部类的initialize方法中,会创建一个SingleThreadScheduledExecutor,并调度内部类运行

我想知道是否有必要在哪里放置同步块(synchronized block)

  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();
}
}
}
}

最佳答案

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

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

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

需要注意的主要更新是对“data”的分配是在 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() );
}
}
}

关于java - 是否有必要对可能被单线程调度程序修改的字段使用 Java 同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55836959/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com