program tip

Understanding java.lang.Thread.State: WAITING (parking)

radiobox 2020. 10. 6. 08:03
반응형

Understanding java.lang.Thread.State: WAITING (parking)


First, a really dumb question, I was just wondering what the waiting 'parking' means ? Is the thread waiting to be parked or is it just been parked and therefore is in wait state ? And when that parking happen, how much cpu/memory resources are taken ? What's the purpose of parking a thread ?

Second, by looking at park method in java thread API

Disables the current thread for thread scheduling purposes unless the permit is available.

If the permit is available then it is consumed and the call returns immediately; otherwise the current thread becomes disabled for thread scheduling purposes and lies dormant until one of three things happens.....

English is not my primary language, so I have some difficulties understanding that, I intended 'permit' as kind of 'permission to park the thread', so the questions that follow:

  • what's the meaning of that, what's 'permit', and who and how is checking those permit ?
  • What does that mean: 'if permit is available then it is consumed', is it getting 'parked' ?
  • following, if second point is true, so what's the difference between 'parking' and 'lies dormant' ? If I have permit I can park it forever and if not, I can make it 'dormant' ?

Thanks


Permit means a permission to continue execution. Parking means suspending execution until permit is available.

Unlike Semaphore's permits, permits of LockSupport are associated with threads (i.e. permit is given to a particular thread) and doesn't accumulate (i.e. there can be only one permit per thread, when thread consumes the permit, it disappears).

You can give permit to a thread by calling unpark(). A thread can suspend its execution until permit is available (or thread is interrupted, or timeout expired, etc) by calling park(). When permit is available, the parked thread consumes it and exits a park() method.


As per the java Thread State Documentation, A thread can go to WAITING state for three reasons:

  1. Object.wait with no timeout
  2. Thread.join with no timeout
  3. LockSupport.park

When you call a park method on a Thread, it disables the thread for thread scheduling purposes unless the permit is available. You can call unpark method to make available the permit for the given thread, if it was not already available.

So, when your Thread is in WAITING mode by LockSupport.park, it will show you as WAITING (parking).

Please make note that, you can call park on current Thread only. This is very helpful mechanism to implement Producer-Consumer Design Pattern.


From the class description (at the top of the LockSupport javadoc) where it describes the permit:

This class associates with each thread that uses it, a permit (in the sense of the Semaphore class). A call to park will return immediately if the permit is available, consuming [the permit] in the process; otherwise [the call to park] may block. A call to unpark makes the permit available, if it was not already available. (Unlike with Semaphores though, permits do not accumulate. There is at most one.)

(I expanded the [text] to make it easier to read for non-English speakers.)

Hopefully somebody with a deeper understanding can elaborate on this. See axtavt's answer.

As a final note, a final quote from the javadoc:

These methods are designed to be used as tools for creating higher-level synchronization utilities, and are not in themselves useful for most concurrency control applications.


The part that made me revisit this question that I could not get around while only reading the documentation was this:

If the permit is available then it is consumed and the call returns immediately...

So how the permit is "available", who and how makes it available, so that it could get consumed immediately? This was somehow trivial to find out:

private static void sleep(long howMuch) {
    try {
        Thread.sleep(howMuch);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) {

    Thread t = new Thread(() -> {
        System.out.println("Sleeping...");
        sleep(2000);
        System.out.println("Parking");
        LockSupport.park();
        System.out.println("After parking");
    });

    sleep(1000);
    t.start();
    System.out.println("Unparking");
    // making the permit available while the thread is running and has not yet
    // taken this permit, thus "LockSupport.park" will return immediately
    LockSupport.unpark(t);

}

The code speaks for itself, the thread is running but not yet called LockSupport.park, while some other thread calls LockSupport.unpark on it - thus making the permit available. After that we call LockSupport.park and that returns immediately since the permit is available.

Once you think about it, this is a bit dangerous, if you expose your threads to some code you do not control and that code calls LockSupport.unpark while you park after that - it might not work.


As i understand it, the "permit" is just an object that represent if a Thread can be "unparked" or not. And this is checked by the Thread itself (or de JRE when you try to park a Thread) The "is consumed" thing, i understand that the permit dissapears and the Thread is not dissabled.

I think you should learn a little bit more about multithreading.. Think of it as a dispenser with Objects called "permit". You tell to a Thread to park, and the Thread check the dispenser, if there is a "permit", the Thread take it and leaves(without park). If there is no "permit" in the dispenser the Thread is parked until a "permit" is avaliable (and you can put a "permit" in the dispenser with unpark.

As for the CPU/memory usage, i think that depends of the OS, etc...

참고URL : https://stackoverflow.com/questions/7497793/understanding-java-lang-thread-state-waiting-parking

반응형