Java 我的自定义异步任务是否应该对传递到构造函数中的内容具有同步访问权限?

Java 我的自定义异步任务是否应该对传递到构造函数中的内容具有同步访问权限?,java,concurrency,synchronization,Java,Concurrency,Synchronization,假设我有一个不可变的模型类: class Model { final String id; Model(String id) { this.id = id; } } class Task extends BlaBlaTask { final Model model; Task(Model model) { this.model = model; } // runs on a background th

假设我有一个不可变的
模型
类:

class Model {
    final String id;
    Model(String id) {
        this.id = id;
    }
}
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;
    }
}
我有一个自定义的
任务
类:

class Model {
    final String id;
    Model(String id) {
        this.id = id;
    }
}
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;
    }
}

另外,我正在使用Java 1.4,代码可能可以在多核CPU上运行。

如果您在后台线程启动之前同时实例化了
任务
(以及在其
模型
之前),那么肯定不需要同步。如果线程已经在运行,而您只是向它提交了一个任务,并且您没有从Java 5的
final
语义中获益,那么理论上可能会有问题,但实际上不太可能出现问题。

如果您同时实例化了
任务
(并且在
模型
之前也进行了实例化)在后台线程启动之前,肯定不需要同步。如果线程已经在运行,而您只是向它提交一个任务,并且您没有从Java 5的
final
语义中获益,那么理论上可能会有问题,但实际上不太可能出现问题。

我不再熟悉Java 1.4的Java内存模型,但我不明白你为什么需要同步

如果您正在启动一个线程,那么新线程将看到您在启动线程之前编写的所有内容


如果要将任务传递给现有线程,则发布机制应该具有所有必要的同步,以确保线程能够看到发布之前编写的所有内容。这不应该是任务的任务来同步任何东西,它应该是队列的任务(或者您用来将任务从一个线程传递到另一个线程的任何其他方式)

我不再熟悉Java 1.4的Java内存模型,但我不明白您为什么需要同步

如果您正在启动一个线程,那么新线程将看到您在启动线程之前编写的所有内容

如果要将任务传递给现有线程,则发布机制应该具有所有必要的同步,以确保线程能够看到发布之前编写的所有内容。这不应该是任务的作业来同步任何内容,它应该是队列的作业(或用于将任务从一个线程传递到另一个线程的任何其他方式)

现在有一个明确的通知:

记忆可观测性 AsyncTask保证所有回调调用在这种情况下同步 一种不需要显式操作就可以确保以下操作安全的方法 同步

  • 在构造函数或onPreExecute()中设置成员字段,并参考 它们位于
    doInBackground(参数…
  • doInBackground(参数…
    中设置成员字段,并在中引用它们
    onProgressUpdate(进度…
    onPostExecute(结果)
这正是我要找的

现在有一个明确的通知:

记忆可观测性 AsyncTask保证所有回调调用在这种情况下同步 一种不需要显式操作就可以确保以下操作安全的方法 同步

  • 在构造函数或onPreExecute()中设置成员字段,并参考 它们位于
    doInBackground(参数…
  • doInBackground(参数…
    中设置成员字段,并在中引用它们
    onProgressUpdate(进度…
    onPostExecute(结果)

这正是我要找的

谢谢,我问了一个被这个问题弄糊涂了的问题:你能看看我的另一个问题吗:?那又是我。。这个问题的答案已经改变了。新的一点是,即使在单核CPU上,可见性仍然可能是一个问题。请您修改一下好吗?AsyncTask API现在有一个关于内存可观察性的明确通知。谢谢,我问了一个被这个问题弄糊涂了的问题:您能看看我的另一个问题吗:?又是我。。这个问题的答案已经改变了。新的一点是,即使在单核CPU上,可见性仍然可能是一个问题。您可以修改它吗?AsyncTaskAPI现在有一个关于内存可观察性的明确通知。