虚拟线程特性的推出,绝对是java继jdk8之后最值得开发人员高兴的特性之一了,在实现高并发场景中,线程是阻碍并发度的一个最关键的指标,由于每个连接都需要一个线程来处理连接,而java中的线程是通过操作系统线程实现的,这就导致一个java应用不能创建太多的线程来处理连接,所以在java中一般是通过线程池的方式来处理请求:指定线程池大小来处理任务,如果任务继续提交就通过缓冲队列来排队。但是这样就会导致另外的问题,一般web端的请求都会设置超时时间,如果在指定时间内服务端没有给出响应,客户端就会断开连接,这就非常影响服务的体验。所以为了达到高并发的需求,项目都是通过集群化部署方式来解决的。
我们知道,web服务大部分是属于IO密集型,IO密集型的应用一般都需要大量的线程,所以虚拟线程非常适合这种场景,大量的虚拟线程运行在少量的平台线程上,JVM调度多个虚拟线程在特定平台线程上执行,并且在平台线程上一次只执行一个虚拟线程。
说了很多,下面介绍一下虚拟线程创建API,为了简化重复代码的编写,首先创建一个公共Runnable实现类:
public class DemoThread implements Runnable {
@Override
public void run() {
System.out.println("线程ID : " + Thread.currentThread().threadId() + "|线程名 : " + Thread.currentThread().getName() + "|是否为虚拟线程 : " + Thread.currentThread().isVirtual());
}
}
下面通过4个api来实现虚拟线程:
- 直接通过Thread.startVirtualThread()创建并启动一个虚拟线程:
Thread.startVirtualThread(new DemoThread());
- 首先通过Thread.ofVirtual()unstarted()创建一个虚拟线程,在通过start()方法启动该线程:
Thread t1 = Thread.ofVirtual().name("virtualThread-1").unstarted(new DemoThread());
t1.start();
- 通过Executors.newVirtualThreadPerTaskExecutor()创建一个ExecutorService,再通过它的submit()方法提交任务:
try(ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor()) {
executorService.submit(new DemoThread());
}
- 通过Thread.ofVirtual().factory()创建一个虚拟线程工厂,再通过该工厂创建虚拟线程并启动:
ThreadFactory factory = Thread.ofVirtual().factory();
Thread t2 = factory.newThread(new DemoThread());
t2.start();
虚拟线程推出后,原有创建线程的方式仍然可以使用,并且也推出了一个新的api用于创建线程:
Thread t3 = Thread.ofPlatform().unstarted(new DemoThread());
t3.start();
这里需要注意一个事情,当主线程执行完毕后,它并不会等待虚拟线程执行完成在退出,所以要想等待虚拟线程执行结果,就需要在线程启动后执行:t1.join(); 等待结果。
public class MyThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
// 返回一个虚拟线程
// return Thread.ofVirtual().name("virtual-1").unstarted(r);
// 返回一个平台线程
return Thread.ofPlatform().name("platform-1").unstarted(r);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/181852.html