2013-03-22 61 views
1

我有一個看起來像這樣的方法:(我已經大大簡化的例子)在AsyncTask的doInBackground()方法中使用這些變量是否安全?

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

是明智的做法是直接使用AsyncTaskdoInBackground()內提供給doSomething()參數方法?或者這會導致線程相關的問題?

此外,如果第三個參數是Context實例而不是String,它會有什麼區別嗎?

+0

您只是傳遞/使用值。例如你沒有傳入'num1',但是它的值可以是1或2,或者是任何'int'。如果你傳遞了一些可變對象的引用,可能會有意義。 – 2013-03-22 23:05:30

+0

Java中的所有內容都是按值傳遞的。因此,做這個事情的論點是不爭的。如果你從另一個線程調用doSomething,它的棧幀將包含另一組副本。即使是String對象也是通過值傳遞的 - 具體地說,是引用值的一個副本。 – Simon 2013-03-22 23:06:57

回答

2

AsyncTask有一些保證,你可以看到它的documentation,但這些主要是關於訪問AsyncTask的領域。

在你的例子中,你正在使用primitives和String。也不能真的被修改,所以你在這方面是安全的。

但是,如果您使用的是可以從另一個線程修改的對象,則無法真正確定在您撥打​​的那一刻和實際使用該對象之間它不會被修改,當你在doInBackground()中讀取它時,它不會被改變,或者更糟糕的是,當你試圖在doInBackground()內修改它並且可能以損壞狀態結束時它將被修改。對於這些情況,您需要使用同步來確保一次只有一個線程可以讀取或修改此類對象。

如果您需要保持對象的值/狀態,因爲您在doInBackground()中調用​​時需要保留該對象的值/狀態,您可能需要克隆它並將此克隆用作快照。

0

只要您僅傳遞原始圖片和/或對immutable objects的引用,這是安全的。否則,您需要確保沒有其他線程將修改這些對象的狀態(或同步對其的訪問)。

由於String s在Java中是不可變的,所以你的例子看起來很好。

相關問題