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

时间:2011-09-21 09:48:54

标签: java multithreading

首先,一个非常愚蠢的问题,我只是想知道等待'停车'意味着什么?线程是等待停放还是刚停放,因此处于等待状态?当停车发生时,需要多少CPU /内存资源?停放线程的目的是什么?

其次,通过查看java thread API

中的park方法
  

除非许可证可用,否则禁用当前线程以进行线程调度。

     

如果许可证可用,那么它被消耗并且呼叫立即返回;否则当前线程因线程调度而被禁用,并且在发生三件事之一之前处于休眠状态.....

英语不是我的主要语言,所以我很难理解,我打算“允许”作为“允许停放线程”,所以接下来的问题:

  • 这是什么意思,什么是“许可”,以及检查这些许可的人和方式是什么?
  • 这是什么意思:'如果有许可证就可以消费',它是否被“停放”?
  • 以下,如果第二点是真的,那么'停车'和'休眠'之间有什么区别?如果我有许可证我可以永久停放,如果没有,我可以让它“休眠”吗?

由于

5 个答案:

答案 0 :(得分:31)

许可是指继续执行的权限。停车意味着暂停执行,直到获得许可。

Semaphore的许可不同,LockSupport的许可与线程相关(即许可被赋予特定的线程)并且不会累积(即每个线程只能有一个许可,当线程消耗许可证时,它就会消失。)

您可以致电unpark()给线程许可。线程可以通过调用park()暂停其执行,直到permit可用(或线程被中断,或超时到期等)。当许可证可用时,停放的线程会使用它并退出park()方法。

答案 1 :(得分:9)

根据java Thread State Documentation,一个线程可以进入WAITING状态有三个原因:

  1. 没有超时的Object.wait
  2. 没有超时的Thread.join
  3. LockSupport.park
  4. 当您在线程上调用park方法时,除非许可证可用,否则它会禁用线程以进行线程调度。您可以调用unpark方法为给定线程提供许可证(如果它尚不可用)。

    因此,当你的Thread通过LockSupport.park处于WAITING模式时,它会显示为WAITING(停车)。

    请注意,您只能在当前线程上拨打park。这是实现Producer-Consumer Design Pattern的非常有用的机制。

答案 2 :(得分:2)

从描述许可证的类描述(在LockSupport javadoc的顶部):

  

此类与使用它的每个线程相关联,允许(在Semaphore类的意义上)。如果许可证可用,将立即返回停车呼叫,在此过程中消耗 [许可证] ;否则 [对公园的召唤] 可能会阻止。如果尚未提供许可证,则拨打unpark会使许可证可用。 (与信号量不同,许可证不会累积。最多只有一个。)

(我扩展了 [text] ,让非英语人士更容易阅读。)

希望有更深入了解的人可以详细说明这一点。请参阅axtavt的回答。

最后一点,来自javadoc的最终引用:

  

这些方法旨在用作创建更高级别同步实用程序的工具,并且对于大多数并发控制应用程序本身并不有用。

答案 3 :(得分:1)

让我重新审视这个问题的部分是我仅阅读文档便无法解决的:

  

如果许可证可用,则将其消耗掉,并且呼叫将立即返回...

那么许可证如何“可用”,谁以及如何使它可用,以便可以立即使用它?找出原因很简单:

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);

}

代码说明了一切,thread正在运行但尚未称为LockSupport.park,而其他一些线程在其上调用LockSupport.unpark-因此可用的许可证。之后,我们致电LockSupport.park,由于获得了许可证,该费用会立即返回。

一旦考虑一下,这将有些危险,如果将线程暴露给您无法控制的某些代码,而之后LockSupport.unpark时该代码调用park,则可能无法正常工作

答案 4 :(得分:0)

据我了解,“permit”只是一个对象,表示Thread是否可以“取消停放”。这是由线程本身(或当您尝试停止线程时de JRE)检查 “被消费”的东西,我明白许可证消失,线程不会被遗弃。

我认为你应该多学习多线程。把它想象成一个叫做“许可”的对象的分配器。你告诉一个线程停放,并且线程检查分配器,如果有“许可”,则线程接受并离开(没有停放)。如果分配器中没有“许可证”,则停止螺纹直到“许可”可用(并且您可以在unpark的分配器中放置“许可证”。

至于CPU /内存使用情况,我认为这取决于操作系统等......