2012-11-16 17 views
0

假設我有一個不變的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; 
    } 
} 

而且兩者ModelTask實例在主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; 
    } 
} 

P.S.我正在研究Java 1.4,並且代碼可能可以在多核CPU上運行。

回答

2

我不熟悉Java 1.4的Java內存模型,但我不明白爲什麼需要同步。

如果您正在啓動一個線程,那麼新線程會在啓動線程之前看到您已寫入的所有內容。

如果您將任務傳遞給現有線程,則發佈機制應具有所有必需的同步以確保線程能夠看到發佈之前已寫入的所有內容。這應該不是同步任務的任務,它應該是隊列的工作(或者任何其他用於將任務從一個線程傳遞到另一個線程的方式)

+0

謝謝,我問這個問題被這個混淆:http://stackoverflow.com/questions/1919469/question-about-java-concurrency-in-practice-example –

+0

請你看看我的另一個問題:http ://stackoverflow.com/questions/12934511/possible-concurrency-issue-in-xlet-development? –

+0

你得到的答案已經很好。我把它提高了。 –

1

如果在後臺線程啓動之前實例化了Task(以及之前的Model),那麼肯定沒有必要進行同步。如果線程已經運行,並且您只是向其提交任務,並且您沒有從Java 5的語義中受益,理論上可能存在問題,但在實踐中實際上不太可能發生。

0

AsyncTask API現在有一個明確的通知:

內存可觀測

的AsyncTask保證所有的回調調用在這種 同步的方式,下面的操作是沒有明確的 同步安全。

  • 在構造函數或onPreExecute()組成員字段,並參考 他們doInBackground(Params...)
  • doInBackground(Params...)中設置成員字段,並參考 onProgressUpdate(Progress...)onPostExecute(Result)

這正是我一直在尋找的!

相關問題