安全点和预分配文件

前言

看博客的时候看到一个有趣的文章 https://juejin.cn/post/7139741080597037063,讲的是在一个for循环中加入了Thread.sleep(0),看似无用的代码其实有很多学问。    在此做个简化和总结。
  • 为什么要加Thread.sleep(0)
    涉及到了安全点(safepoint),为了能够让jvm发现并进行垃圾回收,我们用原作者的一个例子说明一下
public class MainTest {

    public static AtomicInteger num = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        Runnable runnable=()->{
            for (int i = 0; i < 1000000000; i++) {
                num.getAndAdd(1);
            }
            System.out.println(Thread.currentThread().getName()+"执行结束!");
        };

        Thread t1 = new Thread(runnable);
        Thread t2 = new Thread(runnable);
        t1.start();
        t2.start();
        Thread.sleep(1000);
        System.out.println("num = " + num);
    }
}

按照代码来看,主线程休眠 1000ms 后就会输出结果,但是实际情况却是主线程一直在等待 t1,t2 执行结束才继续执行。
在这里插入图片描述
这就是一种可数循环。
这个程序发生了什么事情呢?

1.启动了两个长的、不间断的循环(内部没有安全点检查)。
2.主线程进入睡眠状态 1 秒钟。
3.在1000 ms之后,JVM尝试在Safepoint停止,以便Java线程进行定期清理,但是直到可数循环完成后才能执行此操作。
4.主线程的 Thread.sleep 方法从 native 返回,发现安全点操作正在进行中,于是把自己挂起,直到操作结束。

当我们把for循环中的int改成long后就正常了
在这里插入图片描述
我们使用Thread.sleep(0)测试一下

 Runnable runnable=()->{
                    for (int i = 0; i < 1000000000; i++) {
                        num.getAndAdd(1);

                        if(i % 1000 ==0) {
                            try {
                                Thread.sleep(0);
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
                        }
                    }
                    System.out.println(Thread.currentThread().getName()+"执行结束!");
                };

                Thread t1 = new Thread(runnable);
                Thread t2 = new Thread(runnable);
                t1.start();
                t2.start();
                Thread.sleep(1000);
                System.out.println("num = " + num);

执行结果:
在这里插入图片描述
这样,即使 for 循环的对象是 int 类型,也可以按照预期执行。因为我们相当于在循环体中插入了 Safepoint。

  • 预分配文件
    在这里插入图片描述

在这里插入图片描述

关于什么事安全点(safepoint)和什么是可数循环请看前言中原作者的文章,写的非常棒。
预分配文件也可以在原文章中看到,这里只是做一个简单的总结,谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值