我有一个Android应用程序对象(虽然这纯粹是我认为的java问题),如下所示
我想了解我使用volatile的方式是否正确,我已将Application中的appData定义为volatile,这是否自动保证AppData对象内的所有变量(每个变量都是像数组一样的复杂对象本身)也是不稳定的,或者我是否需要明确地使它们变得像我所做的那样不稳定
另外,正如我在标记为QUESTION的注释中提到的那样,将新变量X等同于一个volatile变量也会使X变得不稳定?
public class App extends Application{
private volatile static AppData appData;
public void fetchMePageInfo(long idOfUserIfNotForSelf) {
RestService.getMePageInfo(new Callback<MePageInfo>() { // RestService is just another class that calls Web server, and has static method getMepageInfo
@Override
public void success(MePageInfo newMePageInfo, Response response) {
// for successful server request, store the newly fetched me page in array
// and set ref to both self me page ref = me page to be displayed = new object,
ArrayList<MePageInfo> mPageInfoList = appData.getMePageInfoList();
// QUESTION : AppData is volatile, but does that mean mPageInfoList is also threadsafe?
MePageInfo selfRef = appData.getUserMePageInfo();
if (selfRef != null) {
// if me page exists already, additionally remove the existing me page first
mPageInfoList.remove(selfRef);
}
mPageInfoList.add(newMePageInfo);
appData.setUserMePageInfo(newMePageInfo); // does not automatically call change listeners
}
});
}
}
public class AppData {
/**
this has the MePageInfo objects of the various other users that the logged in user might go to
for quick fetch, instead of calling server each time
**/
volatile ArrayList<MePageInfo> mePageInfoList = new ArrayList<MePageInfo>();
// region self Me page info data
/**
* the MePageInfo for the logged in user, this is null initially and is filled by FetchGenericMePageInfo for the user
*/
volatile MePageInfo userMePageInfo = null;
}
答案 0 :(得分:1)
易失性和线程安全不是一回事。 volatile
向您保证
写入volatile
变量并随后读取此变量会在两个线程之间建立一个先发生的关系。
此特定变量的所有读写都是原子的。
这就是它的全部功能。因此,如果您将volatile
变量的值分配给另一个变量,则不会使其成为volatile
。线程安全的概念更复杂,变量为volatile
的事实并不意味着即使这个变量本身也是线程安全的。
答案 1 :(得分:1)
存在&#34;不稳定&#34;是变量的属性,而不是它引用的对象的属性。所以(假设我们在这里讨论参考变量,而不是原语),标记变量&#34; volatile&#34;不会使对象线程安全。并且您可能有一个易失性变量和一个非易失性变量,它们都引用同一个对象。
因此,当您将引用变量标记为&#34; volatile&#34;时,您说其他线程可能会使变量引用不同的对象。你并不是说其他线程可能会改变它引用的对象。
因此,为了回答您的第一个问题,对象内的字段的波动性完全独立于引用该对象的任何变量的波动性。回答第二个问题,变量不能通过引用易失性对象而变得易变。
答案 2 :(得分:0)
这会自动保证AppData对象中的所有变量(每个变量都是数组等复杂对象)
没有。做类似的事情:
appData = new AppData();
appData.mePageInfoList = new ArrayList<>();
不是线程安全的。对mePageInfoList
的写入可以不按顺序读取。所以为了回答你的问题,没有人会知道何时会读到AppData
内的字段。
我是否需要像我一样明确地使它们变得不稳定
是的,但即便如此,你也不一定安全。例如,ArrayList
不是线程安全的,因此分配给mePageInfoList
将是线程安全的,但任何后来的集合变异都将存在风险。
将一个新变量X等同于一个volatile变量也会使X变得不稳定吗?
不完全确定你在问什么,你能举个例子吗?