线程不够用怎么办?

简介: ### 并发编程挑战与解决方案概览- 多线程导致线程爆炸,浪费CPU及可能导致JVM崩溃。线程池缓解问题,但仍有阻塞IO的效率低下。- 非阻塞IO(如servlet3.1/Tomcat)和事件驱动(Reactive/Future)减少线程使用,但学习曲线陡峭。- 轻量级线程如Netty、Spring Flux和虚拟线程(Java Loom)提升性能,但普及尚需时日。Java21引入虚拟线程,有望成未来性能关键。

一、同步并发编程困境-线程爆炸

为了提高系统利用率,进程发展到多线程,但是多线程并不完美
image.png

  1. 问题 1:线程等待或线程阻塞。CPU浪费。线程池满而拒绝服务。
  2. 问题 2:创建更多线程可能会导致 JVM 崩溃(内存不足)。每个线程大概需要占用1M内存。

一) 典型线程池应用

image.png

二、技术的发展和探索

一)提高线程利用率:阻塞IO和非阻塞IO

  1. 阻塞IO:image.png
  2. 非阻塞IO:image.png
  3. servlet3.1和tomcat对非阻塞IO的支持:image.png

二)减少线程使用(不阻塞线程):事件驱动, Reactive, Future

  1. 事件驱动:image.png
  2. Reactive响应式编程: image.png
  3. Spring Future异步方法编排: image.png

三)非阻塞NIO和事件驱动结合:Netty和HSF异步,HttpAsyncClient, 异步Tair

  1. Netty:image.png
  2. SpringFlux:image.png
  3. Apache的HttpAsyncClient
  4. Tair异步SDK

四)轻量级线程:纤程(Fiber),协程(coroutine),虚拟线程(VirtualThread)

异步响应式的问题:1. 需要学习一种新的编程模式,学习曲线略高。 2. 调用追踪困难。3. 只要有一个库不支持响应式就会导致响应式失效。

image.png

void handle(Request request, Response response) {
    var url1 = ...
    var url2 = ...

    try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
        var future1 = executor.submit(() -> fetchURL(url1));
        var future2 = executor.submit(() -> fetchURL(url2));
        response.send(future1.get() + future2.get());
    } catch (ExecutionException | InterruptedException e) {
        response.fail(e);
    }
}

String fetchURL(URL url) throws IOException {
    try (var in = url.openStream()) {
        return new String(in.readAllBytes(), StandardCharsets.UTF_8);
    }
}

三、总结

随着Java的发展,Java21发布集成了ProjectLoom,Java正式支持了虚拟线程。虚拟线程基本上会成为下一代Java性能爆发的利器。但是目前国内主流的服务器Java版本还停留在Java8版本,而国外基本上也停留在Java11版本。距离大家真正使用上虚拟现成可能还有一段时间。大家可以根据自己的项目环境,结合上面的技术提升现有的项目吞吐能力。

相关文章
|
8月前
|
Java Linux API
线程的认识
线程的认识
|
4月前
线程18
线程18
40 4
|
4月前
|
安全 Java
线程(二)
线程(二)
|
Java C语言 Python
线程那些事
线程那些事
57 0
|
8月前
|
C#
C#线程初步
C#线程初步
42 0
|
Java Linux 程序员
04.关于线程你必须知道的8个问题(下)
大家好,我是王有志。今天是Java面试中线程问题的最后一部分内容,包括我们来聊同步与互斥,线程的本质,调度,死锁以及线程的优缺点等问题。
124 1
04.关于线程你必须知道的8个问题(下)
|
Java
线程理解
个人学习理解
84 0
|
缓存 监控 Java
线程
多线程
114 0
|
Java 编译器 Linux
初识 线程
初识 线程
115 0
初识 线程