简体   繁体   中英

Is the following while loop can be run more than one time?

I found a piece of code in Android src code that is very easy but I can't understand. The following code is a part of a bigger function (I don't think the other part is needed in order to get answer to my question)

timeoutMs = 10000   // timeoutMs is a function parameter but for the example i have initiated it here
 if (timeoutMs > 0) {
      long nowMs = SystemClock.uptimeMillis();
      long deadlineMs = nowMs + timeoutMs;
      while (!isDone() && nowMs < deadlineMs) {
          wait(deadlineMs - nowMs);
          nowMs = SystemClock.uptimeMillis();
     }
 }

It seems that the while loop will be run at most one time (depends on isDone value). Is there a situation the in the second loop the condition: nowMs < deadlineMs is true? The way I see it, in the second condition they are already equal. Is that correct?

You seem to be labouring under a bit of a misconception: wait(100) does not wait 100 milliseconds, You'd think it does (it reads almost like english: literally, "Wait 100"). but it does not. That's not what wait is for. Thread.sleep(100) is java-ese for 'please wait for about 100 milliseconds'. wait(100) is java-ese for: Please wait until a notification arrives. However, try not to wait for longer than 100 milliseconds.

Let me explain: wait(x) is call you make on an object, it's not a utility method. You invoke it on something. In this case, as you just wrote wait and not foo.wait , therefore, you're invoking it on this ; it's the exact same call as this.wait(100) . This means two things: [A] this code must be within a syncronized(this) block, or the wait call will immediately throw an exception (why? Because the wait / notify system decrees it so - see the javadoc of these methods. The methods are in jlObject itself), and crucially [B], this code's primary purpose is to wait until another thread invokes x.notify() or x.notifyAll() , where x resolves to the same object identity that this resolves to in the pasted code. However, the 100 part is like a limit: Try not to wait any longer than that. In other words, the thread will go to sleep, and then wake back up after deadlineMs - nowMs milliseconds or sooner , if this is notify/notifyAlled.

It is possible/likely that you are thinking of Thread.sleep(100) , which does indeed attempt to pause for about 100 milliseconds, and does not play any interruption games. There is no notify part to Thread.sleep , and you don't call sleep on any particular object. It's a static method. The code you pasted will run more than once-through the while loop if this gets notify/notifyAll-ed halfway through.

--EDIT--

Apparently a few further things are unclear:

"Isn't 100 ms is the maximum?"

No. For starters, CPUs and computers aren't usually that accurate unless you go out of your way for it, and shut down everything else it is doing. If after exactly 100ms the CPU is busy juggling a background install of an app update whilst applying HDR to that picture, and uploading another to gdrive, maybe right this very millisecond there isn't any time to run your stuff, maybe in about 5 milliseconds you get to go, at which point it'd be 105 milliseconds since.

Also, wait() implies a lock - the call crashes instantly if you don't have a lock. wait() relinquishes the lock, and before code continues, the lock must be re-acquired or the thread can't unpause. This can take a year if you're unlucky: All other threads that hold the lock must first progress to no longer holding it. This part doesn't apply to Thread.sleep , which is yet another reason why Thread.sleep is simply: "Wait x milliseconds or thereabouts" whereas wait() is a far more complicated beast, that involves both notifications and lock acquiring in addition to a timeout.

What is the meaning of wait(0)? Can't understand argument 0.

That means: Wait until that notify() comes in. Wait forever if you have to.

Thread.sleep(0) is simple: That does nothing (wait 0 milliseconds - okay, done. That was easy). Remember, the primary purpose of wait() is to wait for some other thread to run the code x.notify() , where x is the the same object you called wait() on , and the timeout is an afterthought. 0 means: No timeout, and is the default behaviour (there is a wait() method too, which is just wait(0) ).

It can be any amount of time less than 'timeout' milliseconds.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM