在AsyncTask的doInBackground()方法中使用这些变量是否安全?

时间:2013-03-22 22:56:03

标签: java android android-asynctask thread-safety

我有一个看起来像这样的方法:

public void doSomething(final int num1, final int num2, final String str) {
    new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            reallyComplexStatisticFunction(num1 + num2, str);
        }
    }.execute();
}

(我已经大大简化了这个例子。)

doSomething()的{​​{1}}方法中直接使用提供给AsyncTask的参数是明智的吗?或者这会导致与线程相关的问题吗?

此外,如果第三个参数是Context个实例而不是doInBackground(),会有什么不同吗?

2 个答案:

答案 0 :(得分:2)

AsyncTask有一些保证,你可以在documentation中看到,但这些保证主要是关于AsyncTask字段的访问。

在您的示例中,您使用的是基元和字符串。两者都不能真正被修改,所以你在那方面是安全的。

但是,如果你正在使用一个可以从另一个线程修改的对象,那么你无法确定在你调用execute()和实际使用它之间不会修改它。对象,它在doInBackground()内部读取时不会被更改,或者更糟糕的是,当您尝试在doInBackground()内修改它并且可能以损坏的状态结束时它将被修改。对于这些情况,您需要使用同步来确保一次只能有一个线程读取或修改此类对象。

如果您需要保持对象的值/状态,就像在execute()中使用它时调用doInBackground()那样,您可能希望克隆它并将此克隆用作快照。

答案 1 :(得分:0)

只要您只传递immutable objects的原语和/或引用,这是安全的。否则,您需要确保没有其他线程会修改这些对象的状态(或同步对它的访问)。

由于String在Java中是不可变的,因此您的示例看起来很好。