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

和实例都是在主 UI 线程上创建的ModelTask但是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

I'm not familiar anymore with the Java memory model of Java 1.4, but I don't see why you would need synchronization.

If you're starting a thread, then the new thread will see everything you have written before starting the thread.

And if you're passing the task to an existing thread, the publishing mechanism should have all the necessary synchronization in place to make sure that the thread sees everything that has been written before the publication. That shouldn't be the task's job to synchronize anything, it should be the Queue's job (or any other way you use to pass the task from one thread to the other)

于 2012-11-16T10:42:47.810 回答
1

If you have instantiated both Task (and threrefore its Model as well) before the background thread was started, then there is definitely no synchronization necessary. If the thread is already running and you are just submitting a task to it, and you don't benefit from Java 5's final semantics, there may theoretically be a problem, but it is quite unlikely to actually occur in practice.

于 2012-11-16T10:40:39.860 回答
0

AsyncTask API now has an explicit notice on this:

Memory observability

AsyncTask guarantees that all callback calls are synchronized in such a way that the following operations are safe without explicit synchronizations.

  • Set member fields in the constructor or onPreExecute(), and refer to them in doInBackground(Params...).
  • Set member fields in doInBackground(Params...), and refer to them in onProgressUpdate(Progress...) and onPostExecute(Result).

This is exactly what I was looking for!

于 2014-08-11T20:23:58.573 回答