[英]Worker/Background Thread “smothers” UI thread Android- Why?
因此,在AsyncTask派生類內部的doInBackground()中運行以下方法時:
void waitUntilButtonClicked(){
while(true){
synchronized (buttonClicked){
if(buttonClicked) return;
}
try{Thread.sleep(1);} catch(InterruptedException e){};
}
如果沒有最后一行代碼使后台線程休眠1 ms,則用戶界面將不起作用(有一個EditText小部件,當點擊該按鈕時根本不響應)。 我應該提到的是,當waitUntilButtonClicked()運行時,UI線程不會運行任何東西(或者不是我的任何代碼)。
我的問題是我不得不為所有工作添加最后一行。 我以為后台線程不能阻止UI線程,除非程序員方面有很大的錯誤。 為什么會發生? 是的,我已經找到了解決該問題的“方法”,我的解決方案是這樣做的常用方法嗎? 有沒有更好的辦法?
為什么會發生?
您正在忙碌的旋轉循環中占用CPU,從而耗盡了CPU周期的所有其他時間。
是的,我已經找到了解決該問題的“方法”,我的解決方案是這樣做的常用方法嗎?
不,因為睡覺使忙碌的自旋循環不那么忙,通常被認為是不良的形式 。
有沒有更好的辦法?
讓我們假設,在給定代碼的情況下,您擁有一個Button
,並且在單擊Button
時,您想要在后台線程中工作。
如果是這樣,您可以:
只有用叉子叉線,一旦Button
被點擊時,在onClick()
的Button
維護一個線程池(例如Executors.newSingleThreadExecutor()
),然后在Button
的onClick()
中將作業發布到該線程池中
使用startService()
在Button
的onClick()
啟動一個IntentService
,其中IntentService
在onHandleIntent()
中進行工作onHandleIntent()
在后台線程上調用)
使用HandlerThread
並將onClick()
中的post()
事件添加到該Button
使用中級阻止機制,例如CountDownLatch
或Semaphore
,在其中以這種方式觸發后台線程,而不是通過boolean
使用嚴重的低級阻止機制,例如Object#wait()
也許還有其他選擇,但是那六個是一個很好的起點。 所有這些情況都使用OS級阻塞原語來將線程標記為已暫停,直到必要為止,而不是使用您不必要地每毫秒喚醒一次線程的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.