jdk19至21——虚拟线程

经过jdk19和jdk20两次预览,在jdk21中虚拟线程正式成为api,由之前的1对1调用系统线程升级到大量虚拟线程对应有限数量系统线程,可以极大的提高并发性能,提高系统线程和cpu的利用率;

主要是对Thread类进行增强,增加了许多新的方法用于处理虚拟线程,例如isVirtual()判断线程是否是虚拟线程,但之前的已经存在的方法没有太大的变动,构造方法也没有增加,之前的功能不会受到影响;

官网说明:JEP 444: Virtual Threads

创建虚拟线程的方法:

1、通过Executors的newVirtualThreadPerTaskExecutor()方法创建,使用方法跟之前的Executor一样:

	@Test
	void test() {
		var executor = Executors.newVirtualThreadPerTaskExecutor();
		executor.submit(() -> {
			System.out.println("executor virtual thread");
		});
	}

2、使用Thread.Builder创建一批相同属性的线程,Thread类新增了ofVirtual()和ofPlatform()方法用于生成虚拟线程和系统平台线程的Builder,Builder的name()方法可以设置线程名称,uncaughtExceptionHandler()方法可以设置未捕获异常,start()方法可以直接启动线程,unstarted()方法可以返回一个Thread对象用户自己决定何时启动,还有一些方法例如daemon()、group()、priority()、stackSize()是ofPlatform()平台线程特有的方法,虚拟线程无法设置的参数:

	@Test
	void test2() {
		Thread.ofVirtual().name("abc").start(() -> {
				System.out.println("Thread.ofVirtual:" + Thread.currentThread().getName());
			});
		Thread unstartedThread = Thread.ofVirtual().name("UnstartedThread").uncaughtExceptionHandler((t,e)->{}).unstarted(() -> {
			Thread currentT = Thread.currentThread();
			System.out.println("thread:%s state:%s isvirtual:%s".formatted(
					currentT.getName(), currentT.getState(), currentT.isVirtual()));
		});
		unstartedThread.start();
		OfPlatform builder = Thread.ofPlatform()
				.name("platformThread_", 100) // 名字前缀+起始编号
//				.daemon(false) // 平台线程特有,虚拟线程全是守护线程
//				.group(null) // 平台线程特有,虚拟线程group名字固定为VirtualThreads
//				.priority(0) // 平台线程特有,虚拟固定为Thread.NORM_PRIORITY
//				.stackSize(100)
				.uncaughtExceptionHandler((t, e) -> {
					System.out.println("线程:%s 未捕获异常:%s".formatted(t, e));
				});
		builder.start(() -> {System.out.println(Thread.currentThread().getName());});
		builder.start(() -> {System.out.println(Thread.currentThread().getName());});
		builder.start(() -> {System.out.println(Thread.currentThread().getName());int i = 1/0;});
	}

3、使用Thread的startVirtualThread()直接快速创建并运行虚拟线程:

	@Test
	void test3() {
		Thread.startVirtualThread(() -> {
			System.out.println("---" + Thread.currentThread());
			Map<Thread, StackTraceElement[]> allPlatformThread = Thread.getAllStackTraces(); // 全部平台线程,非全部线程(平台、虚拟)
			allPlatformThread.keySet().forEach(System.out::println);
		});
	}

需要注意的地方:

1、虚拟线程是大量的和低成本的,不需要池化;

2、有两种情况虚拟线程阻塞不会释放平台线程:使用synchronized修饰时和调用native方法或者foreign函数时,推荐使用java.util.concurrent.locks.ReentrantLock处理;

3、Thread的public构造方法无法创建虚拟线程,虚拟线程全是守护线程,优先级固定为Thread.NORM_PRIORITY,没有线程组,getThreadGroup()也只会返回一个固定的叫VirtualThreads的组;

4、Thread.getAllStackTraces()返回的是平台级线程,并非平台线程和虚拟线程全部的线程;

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值