简体   繁体   English

理解java.lang.Thread.State:WAITING(停车)

[英]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 ?当停车发生时,占用了多少 CPU/内存资源? What's the purpose of parking a thread ?停放线程的目的是什么?

Second, by looking at park method in java thread API二、通过查看java线程API中的park方法

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 (ie permit is given to a particular thread) and doesn't accumulate (ie there can be only one permit per thread, when thread consumes the permit, it disappears).Semaphore的许可不同, LockSupport的许可与线程相关联(即许可被授予特定线程)并且不会累积(即每个线程只能有一个许可,当线程消耗该许可时,它就会消失)。

You can give permit to a thread by calling unpark() .您可以通过调用unpark()来授予线程许可。 A thread can suspend its execution until permit is available (or thread is interrupted, or timeout expired, etc) by calling park() .线程可以通过调用park()暂停其执行,直到许可可用(或线程被中断,或超时到期等park() When permit is available, the parked thread consumes it and exits a park() method.当 permit 可用时,停放的线程使用它并退出park()方法。

As per the java Thread State Documentation , A thread can go to WAITING state for three reasons:根据 java Thread State Documentation ,线程可以出于三个原因进入 WAITING 状态:

  1. Object.wait with no timeout Object.wait 没有超时
  2. Thread.join with no timeout Thread.join 没有超时
  3. LockSupport.park LockSupport.park

When you call a park method on a Thread, it disables the thread for thread scheduling purposes unless the permit is available.当您在线程上调用 park 方法时,除非许可可用,否则它会出于线程调度目的禁用该线程。 You can call unpark method to make available the permit for the given thread, if it was not already available.您可以调用 unpark 方法以使给定线程的许可可用(如果它尚未可用)。

So, when your Thread is in WAITING mode by LockSupport.park, it will show you as WAITING (parking).因此,当您的线程通过 LockSupport.park 处于 WAITING 模式时,它将显示您为 WAITING(停车)。

Please make note that, you can call park on current Thread only.请注意,您只能在当前线程上调用park。 This is very helpful mechanism to implement Producer-Consumer Design Pattern.这是实现生产者-消费者设计模式非常有用的机制。

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.代码不言自明, thread正在运行但尚未调用LockSupport.park ,而其他一些线程对其调用LockSupport.unpark - 从而使许可可用。 After that we call LockSupport.park and that returns immediately since the permit is available.之后我们调用LockSupport.park并立即返回,因为许可证可用。

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.仔细考虑一下,这有点危险,如果您将线程暴露给一些您无法控制的代码,并且该代码在您park之后调用LockSupport.unpark - 它可能不起作用。

From the class description (at the top of the LockSupport javadoc ) where it describes the permit:从类描述(在LockSupport javadoc的顶部),它描述了许可:

This class associates with each thread that uses it, a permit (in the sense of the Semaphore class).此类与使用它的每个线程相关联,即一个许可(在 Semaphore 类的意义上)。 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.如果许可证不可用,则调用 unpark 可使许可证可用。 (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.) (我扩展了[text]以使非英语人士更容易阅读。)

Hopefully somebody with a deeper understanding can elaborate on this. 希望有更深入了解的人可以详细说明这一点。 See axtavt's answer.请参阅 axtavt 的回答。

As a final note, a final quote from the javadoc:最后,引用来自 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.这些方法旨在用作创建更高级别同步实用程序的工具,并且它们本身对大多数并发控制应用程序没有用处。

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.这由线程本身(或当您尝试停放线程时 de JRE)检查“被消耗”的事情,我知道许可证消失并且线程没有被禁用。

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 .如果分配器中没有“许可”,则线程将停放,直到“许可”可用(您可以使用unpark在分配器中放置“许可”。

As for the CPU/memory usage, i think that depends of the OS, etc...至于 CPU/内存使用情况,我认为这取决于操作系统等...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 java.lang.Thread.State:等待(停车) - java.lang.Thread.State: WAITING (parking) java.lang.Thread.State中90%线程分析:WAITING(停车) - Analysis of 90% threads in java.lang.Thread.State: WAITING (parking) 线程处于等待状态:java.lang.Thread.State:正在sun.misc.Unsafe.park(本地方法)等待(停车) - Thread is in WAITING state: java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) java.lang.Thread.State: WAITING (在对象监视器上) - java.lang.Thread.State: WAITING (on object monitor) java.lang.Thread.State:BLOCKED - java.lang.Thread.State: BLOCKED java.lang.Thread.State:封锁在java.lang.Object上 - java.lang.Thread.State: BLOCKED on java.lang.Object 每 n 分钟创建一个新线程(java.lang.Thread.State: WAITING at sun.misc.Unsafe.park(Native Method)) - New thread every n minutes (java.lang.Thread.State: WAITING at sun.misc.Unsafe.park(Native Method)) Java线程转储:“等待锁定”和“等待停放”之间的区别? - Java thread dump: Difference between “waiting to lock” and “parking to wait for”? 池的所有线程都在等待(停车) - All the thread of pool are WAITING (parking) Thread.State: WAITING (parking) vs BLOCKED at sun.misc.Unsafe.park() 有什么区别 - What is the difference between Thread.State: WAITING (parking) vs BLOCKED at sun.misc.Unsafe.park()
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM