[英]Should my custom async task have synchronized access to what is passed into constructor?
假設我有一個不變的Model
類:
class Model {
final String id;
Model(String id) {
this.id = id;
}
}
我有一個自定義的Task
類:
class Task extends BlaBlaTask {
final Model model;
Task(Model model) {
this.model = model;
}
// runs on a background thread
void doInBackground() {
// do smth with model, e.g.:
String id = model.id;
}
}
並且Model
和Task
實例都在主UI線程上創建。 但是doInBackground()
在另一個線程上運行。 此代碼是否錯誤? 我是否應該添加同步,例如:
class Task extends BlaBlaTask {
Model model;
Task(Model model) {
setModel(model);
}
// runs on a background thread
void doInBackground() {
// do smth with model, e.g.:
String id = getModel().id;
}
private synchronized void setModel(Model m) {
model = m;
}
private synchronized Model getModel() {
return model;
}
}
PS我正在使用Java 1.4,並且代碼可能可以在多核CPU上運行。
我不再熟悉Java 1.4的Java內存模型,但是我不明白為什么需要同步。
如果您正在啟動線程,那么新線程將在啟動線程之前看到您編寫的所有內容。
並且,如果將任務傳遞給現有線程,則發布機制應具有所有必要的同步,以確保線程看到發布之前已編寫的所有內容。 那不應該是同步任何任務的任務,而應該是隊列的任務(或者您用來將任務從一個線程傳遞到另一個線程的任何其他方式)。
如果您在啟動后台線程之前都實例化了Task
(以及在其Model
之前),那么絕對沒有必要進行同步。 如果線程已經在運行,而您只是向其提交任務,而您沒有從Java 5的final
語義中受益,那么從理論上講可能會有問題,但實際上不太可能發生。
AsyncTask API現在對此有一個明確的通知:
記憶可觀察性
AsyncTask保證所有回調調用都以這樣的方式同步,使得以下操作在沒有顯式同步的情況下是安全的。
- 在構造函數或
onPreExecute()
設置成員字段,並在doInBackground(Params...)
引用它們。- 在
doInBackground(Params...)
設置成員字段,並在onProgressUpdate(Progress...)
和onPostExecute(Result)
引用它們。
這正是我想要的!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.