首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么log.debug会导致LockSupport.park()失败

为什么log.debug会导致LockSupport.park()失败
EN

Stack Overflow用户
提问于 2022-10-06 14:24:58
回答 1查看 71关注 0票数 0

如代码所示,locksupport.park ()在线程t1中被调用两次。在LockSupport.park ()之后,主线程第一次唤醒线程t1,并使用t1.中断(),然后在t1中调用thread.interrupted ()以清除线程的中断状态。但是Locksupport.park ()不会第二次挂起线程。奇怪的是,在注释掉log.debug(“test.”)之后,locksupport.park ()可以再次暂停线程。原因是什么?

在这里输入图像描述

在这里输入图像描述

代码语言:javascript
复制
@Slf4j
public class Test08Park4 {
    public static void main(String[] args) throws InterruptedException{

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                LockSupport.park();
                /**
                 * With this log print, locksupport.park () cannot stop threads;
                 * If you comment this out, locksupport.park () can stop the thread
                 */
                log.debug("test.......");
                Thread.interrupted();
                LockSupport.park();
                log.debug("finished...");
            }
        });
        t1.start();
        sleep(1000);
        t1.interrupt();
    }
}

如果不评论log.debug(“测试.”)结果是:

代码语言:javascript
复制
22:37:05.435 [Thread-0] DEBUG test.Test08Park4 - test.......
22:37:05.439 [Thread-0] DEBUG test.Test08Park4 - finished...

如果评论log.debug(“测试.”)结果是:

//无

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-06 14:43:55

阅读文档是基本的。

如文档所示,允许伪造地返回LockSupport.park()。换句话说,这些文档逐字逐句地说明:

  • 问:“为什么公园()这么快就叫回来了?”
  • 答:因为JVM觉得很喜欢。

洛克苏波特的锁是线程全局的。对于每个线程,只有一个信号量( LockSupport称之为“许可”),您不能做更多,也不能做得更少。基本上意味着,JVM中的一个系统可以使用它,因为如果两个系统使用它,它们就会相互混淆。

正如医生们所言:

创建锁和其他同步类的基本线程阻塞原语。

这实质上意味着:你为什么要这么做?如果您想要锁定行为,请使用例如来自java.util.concurrent包的java.util.concurrent;这不是针对您的,因此它有各种各样的奇怪之处,例如park()的规则允许虚假返回。

log.debug代码很可能是A出于某种原因调用LockSupport.unpark(ownThread),这意味着下一个park()调用会立即返回,或者B是时间问题。log.debug不是“免费的”,许多日志框架运行“就地”,这意味着,log.debug调用实际上会在磁盘和fsyncs上运行,这意味着,与一般的非磁盘交互java指令(相当于数百条指令)相比,这确实需要很长的时间。这个时间对调度器来说已经足够了,特别是考虑到‘写磁盘’或'fsync‘是一个自然的停止点( java中的线程是先发制人的,但是如果您给调度程序一个暂停线程的借口,它通常会占用它)。

最后,文档是清楚的:你没有得到你的“为什么”问题的答案。规范使JVM可以自由支配,而不必向您解释为什么park()虚假地返回。因此,找出这个案子的原因没有多大意义--即使你有答案,明天也会有不同的原因。如果您的代码无法处理LockSupport.park()上的虚假返回,那么根据定义,您的代码就会中断。即使你能让它在你的机器上工作,今天,在月球的这个阶段,这并不能保证它明天会工作得很好。

一旦您的代码能够处理虚假的返回,找出为什么它在这里虚假返回不再有趣了。因此,解决方案:正确处理虚假的回报。或者,更有可能的是,不要将它用于锁,而是使用一些对最终用户更友好的东西。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73975470

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档