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

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で実行できます。

4

3 に答える 3

2

Java 1.4 の Java メモリー・モデルについてはもう詳しくありませんが、同期が必要な理由がわかりません。

スレッドを開始している場合、新しいスレッドは、スレッドを開始する前に書いたものすべてを見ることができます。

また、タスクを既存のスレッドに渡す場合、パブリッシュ メカニズムには、パブリッシュ前に書き込まれたすべての内容をスレッドが確実に認識できるように、必要なすべての同期が整っている必要があります。それは、何かを同期するためのタスクの仕事であってはなりません。それは、キューの仕事 (または、あるスレッドから別のスレッドにタスクを渡すために使用するその他の方法) であるべきです。

于 2012-11-16T10:42:47.810 に答える
1

バックグラウンドスレッドが開始される前に両方をインスタンス化した場合Task(したがって、その両方もインスタンス化した場合Model)、同期は必要ありません。スレッドがすでに実行されていて、タスクを送信するだけで、Java 5のセマンティクスの恩恵を受けていないfinal場合、理論的には問題がある可能性がありますが、実際には発生する可能性はほとんどありません。

于 2012-11-16T10:40:39.860 に答える