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

理解java.lang.Thread.State:等待(停车),java,multithreading,Java,Multithreading,首先,一个非常愚蠢的问题,我只是想知道等待“停车”是什么意思?线程是正在等待停止,还是刚刚停止,因此处于等待状态?当停车发生时,占用了多少cpu/内存资源?停线的目的是什么 第二,通过观察公园中的方法 除非许可证可用,否则出于线程调度目的禁用当前线程 如果许可证可用,则该许可证被消耗,呼叫立即返回;否则,出于线程调度目的,当前线程将被禁用,并处于休眠状态,直到发生以下三种情况之一 英语不是我的主要语言,因此我在理解上有一些困难,我打算将“许可”作为“允许停线”,因此以下问题: 这是什么意思,什

首先,一个非常愚蠢的问题,我只是想知道等待“停车”是什么意思?线程是正在等待停止,还是刚刚停止,因此处于等待状态?当停车发生时,占用了多少cpu/内存资源?停线的目的是什么

第二,通过观察公园中的方法

除非许可证可用,否则出于线程调度目的禁用当前线程

如果许可证可用,则该许可证被消耗,呼叫立即返回;否则,出于线程调度目的,当前线程将被禁用,并处于休眠状态,直到发生以下三种情况之一

英语不是我的主要语言,因此我在理解上有一些困难,我打算将“许可”作为“允许停线”,因此以下问题:

  • 这是什么意思,什么是“许可证”,谁以及如何检查这些许可证
  • 这是什么意思:“如果许可证可用,那么它就被消耗掉了”,它是否被“停放”了
  • 接下来,如果第二点是真的,“停车”和“休眠”有什么区别?如果我有许可证,我可以永久停车,如果没有,我可以让它‘休眠’

感谢描述许可证的课程描述(在顶部):

这个类与使用它的每个线程相关联,一个许可证(在信号量类的意义上)。如果许可证可用,将立即致电park,并在此过程中使用[许可证];否则[呼叫停车]可能会受阻。调用unpark将使许可证可用(如果尚未可用)。(但与信号灯不同,许可证不会累积。最多有一个。)

(我扩展了[文本]以便于非英语使用者阅读。)

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

最后请注意,javadoc的最后一句话:

这些方法被设计为用作创建更高级别同步实用程序的工具,其本身对大多数并发控制应用程序都没有用处

据我所知,“permit”只是一个对象,表示线程是否可以“unparke”。这是由线程本身检查的(或者当您尝试停驻线程时,由dejre检查) “被消耗”的事情,我知道许可证失效,线程没有失效

我认为您应该学习更多关于多线程的知识。。可以把它想象成一个带有被称为“许可证”的物品的分配器。你告诉一根线停,线检查分配器,如果有“许可证”,线拿着它离开(不停)。如果分配器中没有“许可证”,线程将停止,直到“许可证”可用为止(您可以使用
unpark
将“许可证”放入分配器中)


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

许可意味着允许继续执行。停车意味着在许可可用之前暂停执行

与的许可证不同,
LockSupport
的许可证与线程关联(即,许可证授予特定线程),并且不会累积(即,每个线程只能有一个许可证,当线程使用许可证时,许可证消失)

您可以通过调用
unpark()
将许可证授予线程。线程可以通过调用
park()
暂停其执行,直到许可证可用(或线程中断,或超时过期等)。当许可证可用时,停驻的线程将使用它并退出
park()
方法。

根据java,线程可能会进入等待状态,原因有三:

  • 对象。无超时等待
  • Thread.join没有超时
  • 在线程上调用park方法时,除非许可证可用,否则它会出于线程调度目的禁用该线程。如果给定线程的许可证不可用,可以调用unpark方法使其可用

    因此,当您的线程通过LockSupport.park处于等待模式时,它将显示您正在等待(停止)


    请注意,您只能在当前线程上调用park。这是实现生产者-消费者设计模式的非常有用的机制。

    在阅读文档时,我无法回避这个问题的部分是:

    如果许可证可用,则该许可证将被消耗,呼叫将立即返回

    因此,当许可证“可用”时,是谁以及如何使其可用,从而使其能够立即被消费?这在某种程度上是微不足道的:

    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();
        }
    }    
    
    代码本身就说明了问题,
    线程
    正在运行,但尚未调用
    LockSupport.park
    ,而其他一些线程在其上调用
    LockSupport.unpark
    ,从而使许可证可用。之后,我们调用
    LockSupport.park
    ,这会在许可证可用后立即返回


    仔细想想,这有点危险,如果您将线程暴露于一些您无法控制的代码中,并且该代码调用了
    LockSupport.unpark
    ,而您
    park
    之后,它可能不起作用。

    因此,如果线程a为线程B调用了“park”,但许可证可用,即“B无法驻车”,则call由A直接返回,B没有停车。否则,当没有许可证时,B必须服从。那么,等待(停车)是否意味着“A试图让我停车,因为我没有许可证,但我现在不能这样做,所以我也阻止了A”?很抱歉说了这么长的一句话。我想这种等待相当耗费资源。我仍然想知道是谁在管理整个许可证事务。是谁/什么决定了某些线程有许可证,而其他线程没有。@Leonardo:一个线程只能停驻自己,无法停驻其他线程。因此,调用