[英]Java, why need to use synchronization? instead of using a single thread?
[英]Is it necessary to use Java synchronization on a field that might be modified by a single thread scheduler?
我有一个课程(外语课),以下内容
包含数据的List字段
List字段的getter方法
getDataFromDB方法从在线数据库返回List
一个实现Runnable的内部类,并在其run方法中修改List字段
在outter类的initialize方法中,将设置一个SingleThreadScheduledExecutor,它将调度内部类运行
我想知道是否有必要将同步块放在哪里
在getter方法中读取List字段(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.