JDK21新特性之虚拟线程

背景

我们在Java中经常使用的线程叫做平台线程(Platform Threads)它与操作系统内核空间中的线程对应,它由操作系统进行管理,可创建最大数量受限于操作系统。

在Linux中可以通过cat /proc/sys/kernel/threads-max命令查看操作系统单个进程支持最大线程数量。

在高并发应用中,我们常使用多线程来提高程序处理效率,当线程创建数量达到瓶颈便无法处理更多的请求。线程的管理开销较高,需要CPU频繁切换时间片,而我们池化后也只能解决线程创建和销毁的开销,并不能创建更多的线程数量,也无法解决频繁切换线程开销的问题。

什么是虚拟线程?

虚拟线程(Virtual Threads)也就是其他语言中的协程。例如:Python中的coroutine,GoLang中的goroutine。

为什么要使用虚拟线程?

虚拟线程是以平台线程为载体的轻量级线程,它运行在用户空间内由JVM管理,占用空间更小,同时也能减少线程切换的开销,支持创建更多的虚拟线程,支持更多的并发量,提高性能。可以更有效的利用资源,降低运营成本。

如何创建一个虚拟线程?

方式一

public class Main {

    public static void main(String[] args) {

		// 创建一个平台线程
        Thread.ofPlatform().start(()->{
            System.out.println("pt="+Thread.currentThread());
        });

		// 创建一个虚拟线程
        Thread vt = Thread.ofVirtual().start(() -> {
            System.out.println("vt="+Thread.currentThread());
        });

        // 等待虚拟线程执行完毕,再退出主程序
        vt.join();
        //或使用效果一样 new CountDownLatch(1).await(2, TimeUnit.SECONDS);
    }
}

运行结果:

pt=Thread[#21,Thread-0,5,main]
vt=VirtualThread[#22]/runnable@ForkJoinPool-1-worker-1
vt2=VirtualThread[#24]/runnable@ForkJoinPool-1-worker-2

其中虚拟线程 VirtualThread[#22] 运行在平台线程worker-1中,worker-1ForkJoinPool-1线程池中的线程。

方式二:通过线程池的方式创建虚拟线程

      @Test
    public void testVtExecutor() throws InterruptedException {
        var max = 1_000_000;
        // 创建一个计时器
        CountDownLatch latch = new CountDownLatch(max);
        // 统计平台线程
        Set<String> ptNames = ConcurrentHashMap.newKeySet();
        // 虚拟线程池
        ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
        // 创建100万个虚拟线程
        IntStream.range(0, max).forEach(i ->{
            executor.submit(() -> {
                // 计时器减1
                latch.countDown();
                // 每个虚拟线程 睡眠1秒并统计平台线程名称
                Thread.sleep(Duration.ofSeconds(1));
                ptNames.add(Thread.currentThread().toString().split("@")[1]);// VirtualThread[#9297]/runnable@ForkJoinPool-1-worker-12
                return i;// callable抛出异常
            });
        });
        // 等待统计结果
        latch.await();
        // 打印
        System.out.println("ptNames.size=" + ptNames.size());
    }

运行结果:

ptNames.size=12

可以看到100万个虚拟线程只用了12个平台线程,极大减少了线程创建数量。

虚拟线程原理

一个平台线程对应多个虚拟线程,但不是一一绑定的,每个平台线程会维护一个任务列表,并从此列表获取虚拟线程。

  1. 当虚拟线程启动时,它会绑定到某个平台线程,平台线程作为载体运行在线程池中。
  2. 当虚拟线程阻塞时,它会从平台线程中卸载。这个平台线程就可以运行其他虚拟线程。甚至去其他平台线程中获取任务。
  3. 当虚拟线程恢复到非阻塞时,它会加载到某个平台线程的任务列表中。

这样我们就可以利用少量的平台线程,来运行大量的虚拟线程,从而节省平台线程资源。

虚拟线程的使用场景

  1. 虚拟线程更适合处理阻塞式任务,在阻塞期间将CPU资源让给其他任务来提高效率。
  2. 不适合执行CPU密集型或非阻塞任务,虚拟线程不会运行的更快,只会提高规模。
智能网联汽车的安全员高级考试涉及多个方面的专业知识,包括但不限于自动驾驶技术原理、车辆传感器融合、网络安全防护以及法律法规等内容。以下是针对该主题的一些核心知识解析: ### 关于智能网联车安全员高级考试的核心内容 #### 1. 自动驾驶分级标准 国际自动机工程师学会(SAE International)定义了六个级别的自动驾驶等级,从L0到L5[^1]。其中,L3及以上级别需要安全员具备更高的应急处理能力。 #### 2. 车辆感知系统的组成与功能 智能网联车通常配备多种传感器,如激光雷达、毫米波雷达、摄像头和超声波传感器等。这些设备协同工作以实现环境感知、障碍物检测等功能[^2]。 #### 3. 数据通信与网络安全 智能网联车依赖V2X(Vehicle-to-Everything)技术进行数据交换,在此过程中需防范潜在的网络攻击风险,例如中间人攻击或恶意软件入侵[^3]。 #### 4. 法律法规要求 不同国家和地区对于无人驾驶测试及运营有着严格的规定,考生应熟悉当地交通法典中有关自动化驾驶部分的具体条款[^4]。 ```python # 示例代码:模拟简单决策逻辑 def decide_action(sensor_data): if sensor_data['obstacle'] and not sensor_data['emergency']: return 'slow_down' elif sensor_data['pedestrian_crossing']: return 'stop_and_yield' else: return 'continue_driving' example_input = {'obstacle': True, 'emergency': False, 'pedestrian_crossing': False} action = decide_action(example_input) print(f"Action to take: {action}") ``` 需要注意的是,“同学”作为特定平台上的学习资源名称,并不提供官方认证的标准答案集;建议通过正规渠道获取教材并参加培训课程来准备此类资格认证考试
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值