Java 21 虚拟线程如何限流控制吞吐量

打印 上一主题 下一主题

主题 922|帖子 922|积分 2766

虚拟线程(Virtual Threads)是 Java 21 所有新特性中最为吸引人的内容,它可以大大来简化和增强Java应用的并发性。但是,随着这些变化而来的是如何最好地管理此吞吐量的问题。本文,就让我们看一下开发人员在使用虚拟线程时,应该如何管理吞吐量。
在大多数情况下,开发人员不需要自己创建虚拟线程。例如,对于 Web 应用程序,Tomcat 或 Jetty 等底层框架将为每个传入请求自动生成一个虚拟线程。
如果在应用程序内部需要自行调用来提供业务并发能力时,我们可以使用Java 21新特性:虚拟线程(Virtual Threads)中介绍的方法去创建和使用,比如较为常用的就是Executors.newVirtualThreadPerTaskExecutor()。
  1. Runnable runnable = () -> {
  2.     System.out.println("Hello, www.didispace.com");
  3. };
  4. try (ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor()) {
  5.     for (int i = 0; i < 100; i++) {
  6.         executorService.submit(runnable);
  7.     }
  8. }
复制代码
我们可以像上面开启100个虚拟线程来执行任务。那么问题来了,我们要如何对虚拟线程限流控制吞吐量呢?
虚拟线程的限流

对于虚拟线程并发控制的答案是:信号量!划重点:不要池化虚拟线程,因为它们不是稀缺资源。所以,对于虚拟线程并发控制的最佳方案是使用java.util.concurrent.Semaphore。
下面的代码示例演示了如何实现java.util.concurrent.Semaphore来控制虚拟线程的并发数量:
  1. public class SemaphoreExample {
  2.     // 定义限流并发的信号量,这里设置为:10
  3.         private static final Semaphore POOL = new Semaphore(10);
  4.         public void callOldService(...) {
  5.                 try{
  6.                         POOL.acquire(); // 尝试通过信号量获取执行许可
  7.                 } catch(InterruptedException e){
  8.             // 执行许可获取失败的异常处理               
  9.                 }
  10.        
  11.                 try {
  12.                         // 获取到执行许可,这里是使用虚拟线程执行任务的逻辑
  13.                 } finally {
  14.             // 释放信号量
  15.                         POOL.release();
  16.                 }
  17.         }
  18. }
复制代码
是不是很简单呢?今天的分享就到这里,希望对你有所帮助,更多关于Java新特性的学习可以关注我的免费专栏Java新特性
扩展阅读

欢迎关注我的公众号:程序猿DD。第一时间了解前沿行业消息、分享深度技术干货、获取优质学习资源

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

傲渊山岳

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表