理解java.lang.Thread.State:等待(停车)
首先,一个非常愚蠢的问题,我只是想知道等待“停车”是什么意思?线程是正在等待停止,还是刚刚停止,因此处于等待状态?当停车发生时,占用了多少cpu/内存资源?停线的目的是什么 第二,通过观察公园中的方法 除非许可证可用,否则出于线程调度目的禁用当前线程 如果许可证可用,则该许可证被消耗,呼叫立即返回;否则,出于线程调度目的,当前线程将被禁用,并处于休眠状态,直到发生以下三种情况之一 英语不是我的主要语言,因此我在理解上有一些困难,我打算将“许可”作为“允许停线”,因此以下问题:理解java.lang.Thread.State:等待(停车),java,multithreading,Java,Multithreading,首先,一个非常愚蠢的问题,我只是想知道等待“停车”是什么意思?线程是正在等待停止,还是刚刚停止,因此处于等待状态?当停车发生时,占用了多少cpu/内存资源?停线的目的是什么 第二,通过观察公园中的方法 除非许可证可用,否则出于线程调度目的禁用当前线程 如果许可证可用,则该许可证被消耗,呼叫立即返回;否则,出于线程调度目的,当前线程将被禁用,并处于休眠状态,直到发生以下三种情况之一 英语不是我的主要语言,因此我在理解上有一些困难,我打算将“许可”作为“允许停线”,因此以下问题: 这是什么意思,什
- 这是什么意思,什么是“许可证”,谁以及如何检查这些许可证
- 这是什么意思:“如果许可证可用,那么它就被消耗掉了”,它是否被“停放”了
- 接下来,如果第二点是真的,“停车”和“休眠”有什么区别?如果我有许可证,我可以永久停车,如果没有,我可以让它‘休眠’
感谢描述许可证的课程描述(在顶部): 这个类与使用它的每个线程相关联,一个许可证(在信号量类的意义上)。如果许可证可用,将立即致电park,并在此过程中使用[许可证];否则[呼叫停车]可能会受阻。调用unpark将使许可证可用(如果尚未可用)。(但与信号灯不同,许可证不会累积。最多有一个。) (我扩展了[文本]以便于非英语使用者阅读。) 希望有人有更深的理解可以详细说明这一点。请参阅axtavt的答案 最后请注意,javadoc的最后一句话: 这些方法被设计为用作创建更高级别同步实用程序的工具,其本身对大多数并发控制应用程序都没有用处 据我所知,“permit”只是一个对象,表示线程是否可以“unparke”。这是由线程本身检查的(或者当您尝试停驻线程时,由dejre检查) “被消耗”的事情,我知道许可证失效,线程没有失效 我认为您应该学习更多关于多线程的知识。。可以把它想象成一个带有被称为“许可证”的物品的分配器。你告诉一根线停,线检查分配器,如果有“许可证”,线拿着它离开(不停)。如果分配器中没有“许可证”,线程将停止,直到“许可证”可用为止(您可以使用
unpark
将“许可证”放入分配器中)
至于CPU/内存的使用,我认为这取决于操作系统等。许可意味着允许继续执行。停车意味着在许可可用之前暂停执行 与的许可证不同,
LockSupport
的许可证与线程关联(即,许可证授予特定线程),并且不会累积(即,每个线程只能有一个许可证,当线程使用许可证时,许可证消失)
您可以通过调用unpark()
将许可证授予线程。线程可以通过调用park()
暂停其执行,直到许可证可用(或线程中断,或超时过期等)。当许可证可用时,停驻的线程将使用它并退出park()
方法。根据java,线程可能会进入等待状态,原因有三:
请注意,您只能在当前线程上调用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:一个线程只能停驻自己,无法停驻其他线程。因此,调用