我有一个看起来像这样的方法:
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()
,会有什么不同吗?
答案 0 :(得分:2)
AsyncTask
有一些保证,你可以在documentation中看到,但这些保证主要是关于AsyncTask
字段的访问。
在您的示例中,您使用的是基元和字符串。两者都不能真正被修改,所以你在那方面是安全的。
但是,如果你正在使用一个可以从另一个线程修改的对象,那么你无法确定在你调用execute()
和实际使用它之间不会修改它。对象,它在doInBackground()
内部读取时不会被更改,或者更糟糕的是,当您尝试在doInBackground()
内修改它并且可能以损坏的状态结束时它将被修改。对于这些情况,您需要使用同步来确保一次只能有一个线程读取或修改此类对象。
如果您需要保持对象的值/状态,就像在execute()
中使用它时调用doInBackground()
那样,您可能希望克隆它并将此克隆用作快照。
答案 1 :(得分:0)
只要您只传递immutable objects的原语和/或引用,这是安全的。否则,您需要确保没有其他线程会修改这些对象的状态(或同步对它的访问)。
由于String
在Java中是不可变的,因此您的示例看起来很好。