So when running the following method in doInBackground() inside of AsyncTask derived class:
void waitUntilButtonClicked(){
while(true){
synchronized (buttonClicked){
if(buttonClicked) return;
}
try{Thread.sleep(1);} catch(InterruptedException e){};
}
without the very last line of code which makes the background thread sleep for 1 ms, the User Interface doesn't work (there is an EditText widget which when tapped on doesn't respond at all). I should mention that when waitUntilButtonClicked() runs the UI thread doesn't run anything (or rather not any of my code).
My problem is that I HAD to add the last line for everything to work. I thought that a background thread cannot block the UI thread unless there is a huge error on the programmer's part. Why does it happen? And yes I've figured out a 'way' to overcome that, is my solution a common method of doing that? Is there a better way?
Why does it happen?
You are tying up the CPU in a busy spin loop , starving everything else of CPU cycles.
And yes I've figured out a 'way' to overcome that, is my solution a common method of doing that?
No, as sleeping to make a busy spin loop less busy generally is considered to be poor form .
Is there a better way?
Let's assume, given your code, that you have a Button
, and when the Button
is clicked, you want to do work in a background thread.
If that is the case, you could:
Only fork the thread once the Button
is clicked, in the onClick()
for the Button
Maintain a thread pool (eg, Executors.newSingleThreadExecutor()
), and post a job to that thread pool in the onClick()
for the Button
Use startService()
to kick off an IntentService
in the onClick()
for the Button
, where the IntentService
does the work in onHandleIntent()
(which is called on a background thread)
Use a HandlerThread
and post()
events to it from onClick()
for the Button
Use mid-level blocking mechanisms, like CountDownLatch
or Semaphore
, where you trigger your background thread that way instead of via the boolean
Use seriously low-level blocking mechanisms, like Object#wait()
Probably there are other options as well, but those six would be a good starting point. All of these cases use OS-level blocking primitives to mark a thread as suspended until necessary, rather than your approach of waking up the thread unnecessarily every millisecond.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.