簡體   English   中英

我的自定義異步任務應該對傳遞給構造函數的內容進行同步訪問嗎?

[英]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;
    }
}

並且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;
    }
}

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM