106

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

Community
  • 1
  • 1
Leonardo
  • 9,607
  • 17
  • 49
  • 89

5 Answers5

41

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.

axtavt
  • 239,438
  • 41
  • 511
  • 482
  • 2
    So reassuming, if thread A call 'park' for thread B , but permit is available, which is 'B cannot be parked', then the call made by A just return and B is not parked. Otherwise when no permit is available, B has to obey. So, does the waiting(parking) means "A is trying to parking me because I don't have permit but I cannot do that right now so I am blocking A too" ? Sorry for this long sentence. I suppose this waiting is quite resource consuming. I am still wondering who's managing the whole permit thing. Who/what is deciding that some thread have permit, while others not. – Leonardo Sep 28 '11 at 12:47
  • 2
    @Leonardo: A thread can only park itself, there is no way to park other threads. So, calling `park()` means "I want to suspend my execution until some other thread give me a permit by calling `unpark()`". – axtavt Sep 28 '11 at 12:59
  • So a thread cannot park other threads, but can be unparked by other threads ? Is that correct ? So, when does that parking occurs ? Maybe a thread has no job to do at the moment, and it's way of checking it is by looking constantly at its permit ? This would be well suit for daemon thread for example. – Leonardo Sep 30 '11 at 07:59
  • Also, the WAITING(parking) means that it's waiting to be parked, or its in a wait state after being parked ? Sorry I know this is a dumb question :-) – Leonardo Sep 30 '11 at 08:02
  • 3
    @Leonardo: It means a wait state after being parked. – axtavt Sep 30 '11 at 09:23
14

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.

Vishal K
  • 12,976
  • 2
  • 27
  • 38
Badal
  • 4,078
  • 4
  • 28
  • 28
7

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

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

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

public static void main(String[] args) {

    Thread parkingThread = new Thread(() -> {
        System.out.println("Will go to sleep...");
        sleepTwoSeconds();
        System.out.println("Parking...");
        // this call will return immediately since we have called  LockSupport::unpark
        // before this method is getting called, making the permit available
        LockSupport.park();
        System.out.println("After parking...");
    });

    parkingThread.start();

    // hopefully this 1 second is enough for "parkingThread" to start
    // _before_ we call un-park
    sleepOneSecond();
    System.out.println("Un-parking...");
    // making the permit available while the thread is running and has not yet
    // taken this permit, thus "LockSupport.park" will return immediately
    LockSupport.unpark(parkingThread);

}

private static void sleepTwoSeconds() {
    try {
        Thread.sleep(1000 * 2);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

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

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.

Eugene
  • 117,005
  • 15
  • 201
  • 306
  • Very good point, I would have thought that a permit giving activity - i.e. calling unpark() - is only relevant when a thread is being parked. – Alfred Xiao Mar 28 '20 at 05:52
  • @AlfredXiao agreed, this is something that has surprised me also, but it sort of makes sense, I guess. – Eugene Apr 02 '20 at 18:50
3

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.

Charles Goodwin
  • 6,402
  • 3
  • 34
  • 63
1

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...

Vic
  • 189
  • 1
  • 15