并发编程设计模式——Thread-Per-Message模式(四十二)

最简单实用的分工方法

简述

  1. 同步和互斥相关问题更多地源自微观,而分工问题则是源自宏观
  2. 解决分工问题也有一系列的设计模式,比较常用的主要有 Thread-Per-Message 模式、Worker Thread 模式、生产者 - 消费者模式等等。

 

如何理解 Thread-Per-Message 模式(委托代办)

Thread-Per-Message模式:为每个任务分配一个独立的线程。 经典应用:网络编程里服务端的实现(服务端为每个客户端请求创建一个独立的线程,当线程处理完请求后,自动销毁)。

 

用 Thread 实现 Thread-Per-Message 模式(这个实现用于对比,很坑)

  1. 实现 Thread-Per-Message 模式模拟echo并发编程设计模式——Thread-Per-Message模式(四十二)_第1张图片
  2. 缺点:用Thread实现echo 会很坑,java中线程是个重量级对象创建和销毁消耗资源都很大,既占用内存又耗费时间,高并发场景下每次请求都创建新线程并不合适
  3. 新的希望:最新的解决方案--使用轻量级线程,不过创建成本低,而且创建速度及快且内存占用低。
  4. OpenJDK有个Loom项目,专注于解决轻量级线程问题,毕竟Java当中轻量级线程还没有很成熟,Loom中轻量级线程被称为Fiber

Fiber 实现 Thread-Per-Message 模式

  1. Loom中设计轻量级线程时考虑到了使用以及java线程的现状,采取尽量兼容的方式,降低了使用难度
  2. 案例:用 Fiber 实现 echo 服务,对比Thread改动很小,仅仅把new Thread(()->{...}).start() 换成 Fiber.schedule(()->{})
  3. 并发编程设计模式——Thread-Per-Message模式(四十二)_第2张图片

总结

  1. 关于分工问题,指的是如何高效地拆解任务并分配给线程。例如 Future、CompletableFuture 、CompletionService、Fork/Join 计算框架等,这些工具类都能很好地解决特定应用场景的问题,所以,这些工具类曾经是 Java 语言引以为傲的。不过这些工具类都继承了 Java 语言的老毛病:太复杂。
  2. Thread-Per-Message 模式如果使用线程池方案就会增加复杂度。
  3. Thread-Per-Message 模式在 Java 领域并不是那么知名,根本原因在于 Java 语言里的线程是一个重量级的对象,为每一个任务创建一个线程成本太高,尤其是在高并发领域,基本就不具备可行性。不过这个背景条件目前正在发生巨变,Java 语言未来一定会提供轻量级线程,这样基于轻量级线程实现 Thread-Per-Message 模式就是一个非常靠谱的选择。
  4. 当然,对于一些并发度没那么高的异步场景,例如定时任务,采用 Thread-Per-Message 模式是完全没有问题的。实际工作中,我就见过完全基于 Thread-Per-Message 模式实现的分布式调度框架,这个框架为每个定时任务都分配了一个独立的线程。
  5. 无限制的创建线程会导致OOM

你可能感兴趣的:(并发编程,java)