我在其run
方法結束時再次過一個可運行的情況下,自我安排其自身:主線程:可以運行的程序可以被搶佔嗎?
private class MyRunnable implements Runnable {
private volatile boolean cancelled = false;
private Handler handler;
public MyRunnable(Handler h){
handler = h;
}
@Override
public void run(){
//Do stuff
if(!cancelled){
//Preemtion possible here?
handler.postDelayed(this, 1000);
}
}
public void selfStart(){
cancelled = false;
handler.removeCallbacks(this);
handler.post(this);
}
public void selfCancel(){
cancelled = true;
handler.removeCallbacks(this);
}
}
可運行的計劃是在主線程中調用從selfStart
活動的onStart
第一。
與此同時,可以從活動的onStop
以及廣播接收器中從外部取消可運行子系統(呼叫selfCancel
)。
AFAIK Runnable.run
Activity.onStop
和BroadcastReceiver.onReceive
運行在同一個線程(主要的),所以乍一看我認爲不會有線程安全問題。
但有時看起來,可運行程序正在其run
調用的中間被搶佔,然後它從活動或接收器中被取消,然後恢復並重新安排自己。
這可能嗎?
UPDATE:
我會試着更好地解釋這個問題。上面顯示的類旨在定期在主線程中運行任務。在「do stuff」註釋中,實際上有一些代碼用傳遞給MyRunnable
構造函數的值更新TextView
。該活動取消當前可運行並在收到特定意圖時啓動新運行。儘管當前可運行的程序總是被要求在創建新程序之前自行取消,但有時它會與新程序一起運行,所以文本視圖顯示交替的值。這不是預期的行爲。
我想如果runnable當前正在主線程中運行,它會運行直到完成,然後其他runnables或事件處理程序將被帶出隊列並在需要時執行,但是沒有掛起的事件或runnable可能會「一半執行」。
有兩種在這都涉及到問題的主線程運行的任務:
- R1:本
MyRunnable
自調度任務。運行,然後自我再次延遲1秒。 - R2:請求取消當前的
MyRunnable
實例並創建新的R1'的事件處理程序。這些隨機發生,只執行一次。
我已經考慮了兩種情況。第一個:
- R1已經在主線程中運行。
- R2到達並且在主線程中排隊。
- R1完成運行並重新發布。
- R2運行並刪除R1的回調。
- R1應該永不再運行。
,第二個:
- R1未運行,但計劃。
- R2到達並刪除R1的回調。
- R1應該永不再運行。
從理論上講,如果沒有預設,並且只有一個線程,那麼主線程中有時會出現兩個R1?
如果您僅將Runnable發佈到一個Looper,那麼您描述的內容是不可能的 – pskink
您如何知道可標記的行上的runnable已被佔用?它是否有可能執行handler.post(this),然後結束它的當前運行? – user3118604
@ user3118604我不認爲它被搶佔,這是唯一可能的解釋,我可以找到時,有一個單一的線程。但聽起來很牽強,我不想相信這甚至是可能的。 –