[英]Declaring object reference as volatile in Java?
I have a Spring bean class that look similar to the following: 我有一个看起来类似于以下内容的Spring bean类:
@Component
public class Foo{
private Config conf;
@PostConstruct
public void init(){
conf = ConfigFileLoader.loadConfigFromFile();
}
public Config getConfig(){
return conf;
}
public void updateConfig(){
conf = ConfigFileLoader.loadConfigFromFile();
}
}
ConfigFileLoader.loadConfigFromFile() reads configuration from file and returns a new Config object. ConfigFileLoader.loadConfigFromFile()从文件读取配置,并返回一个新的Config对象。
There are two types of threads: 有两种类型的线程:
My question is this, should i mark the private conf field as volatile or maybe add some kind of synchronisation for conf field? 我的问题是,我应该将私有conf字段标记为volatile还是为conf字段添加某种同步?
My fear is the following scenario: the Updater thread updates the conf reference but the change is never made visible to the reader threads. 我担心的是以下情形:Updater线程更新conf引用,但更改永远不会对读取器线程可见。
Any help or explanation will be appreciated. 任何帮助或解释将不胜感激。
The danger here, whether you use volatile
or whether you take @sibnick's suggestion and use a ReaderWriterLock, is that some thread will hold on to its own, private reference to a Config
object for an extended period of time: 无论您使用
volatile
还是采用@sibnick的建议并使用ReaderWriterLock,这里的危险是某些线程将长时间保留其自己的Config
对象私有引用:
Config myConfig = foo.getConfig();
while (conditionThatWillBeTrueForManyIterations()) {
doSomethingWith(myConfig);
}
It is impossible to write code that will not keep its own private reference for some period of time because whatever you do with the Config
object, you will be doing it outside of the mutex. 这是不可能的编写代码,将未持续的时间,因为无论你用做一段时间自己的私人参考
Config
的对象,你会互斥之外做。
Even if you only write this: 即使你只写这个:
doSomethingWith(foo.getConfig());
It is possible that some other thread will update the configuration in between the foo.getConfig()
call and the doSomethingWith(...)
call. 其他一些线程可能会在
foo.getConfig()
调用与doSomethingWith(...)
调用之间更新配置。
Your program will have to be able to cope with that possibility. 您的程序必须能够应对这种可能性。
Volatile = An attempt that other threads see the updated value of the object's state , no guarantee that threads run in synch and in a manner that they do not enter a situation that the screw up other's(thread(s) ) work 易失性=尝试使其他线程看到对象状态的更新值,不保证线程同步运行,并且不保证它们不会进入破坏他人线程工作的情况
Synchronized code by intrinsic locks = An attempt to make sure threads see the updated object state + guarantee that threads work in synch and wait for each other so that there is no interference. 通过内部锁进行的同步代码=尝试确保线程看到更新的对象状态+保证线程同步工作并互相等待,以防止相互干扰。
The load method you have defined here will have the instruction set which is not atomic .It reads the file and updates the Object it is loaded into. 您在此处定义的装入方法将具有非原子的指令集。它将读取文件并更新要装入的对象。
The read and update operations from a single thread have to be done in a single go in a manner that no other thread interferes and try to redo the same. 必须单次完成从单个线程进行的读取和更新操作,而不会受到其他线程的干扰,并尝试重做相同的操作。
Volatile is not a sure shot solution to your issue as your actions are not a single statement /assignment procedure. 不确定性不是解决问题的可靠方法,因为您的操作不是一个单一的声明/分配过程。
Recommendation is to use : intrinsic locks on an object and make read and update method work in synch . 建议使用:对象上的固有锁,并使读取和更新方法同步运行。
public class Foo{
private Config conf;
Object lock = new Object();
@PostConstruct
public void init(){
synchronize(lock)
{
conf = ConfigFileLoader.loadConfigFromFile();
}
}
public Config getConfig(){
synchronize(lock)
{
return conf;
}
}
public void updateConfig(){
synchronize(lock)
{
conf = ConfigFileLoader.loadConfigFromFile();
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.