什么是协程?Java中如何支持?
协程(Coroutine):是单线程下的并发,又称微线程,纤程。简单理解就是线程中的线程。
优点:
-
轻量,创建成本小,降低了内存消耗
-
用户态调度,减少了 CPU 上下文切换的开销,提高了 CPU 缓存命中率
-
减少同步加锁,提高了性能
-
可以用同步思维写异步代码
缺点:
-
在协程执行中不能有阻塞操作,否则整个线程被阻塞
-
不擅长处理 CPU 密集型
适用场景:
-
高性能要求,考虑牺牲公平性换取吞吐量
-
IO 密集型任务
-
Generator 式的流式计算
Java 官方目前是还没推出协程
目前可用性比较高的有 Quasar 和 ea-async 两个第三方库,都是通过 byte code Instrument,把编译后同步程序class文件修改为异步的操作。
1、Quasar:
https://github.com/puniverse/quasar
提供了Fiber实现,调度器,甚至Channel,Actor编程范式这样的支持
官方示例: https://github.com/puniverse/quasar-mvn-archetype
尝试
package testgrp; import java.util.concurrent.ExecutionException; import co.paralleluniverse.fibers.Fiber; import co.paralleluniverse.fibers.SuspendExecution; import co.paralleluniverse.strands.SuspendableRunnable; public class TestFiber { void startFiber(int num) throws ExecutionException, InterruptedException { for (int i = 0; i < num; i++) { final int index = i; Fiber<Void> fiber = new Fiber<Void>("fiber", new SuspendableRunnable() { @Override public void run() throws SuspendExecution, InterruptedException { System.out.println("fiber-" + index); Fiber.sleep(60000); } }); fiber.start(); } Thread.sleep(60000); } }
package testgrp; import org.junit.Test; public class TestFiberAndThread { @Test public void test() throws Exception { new TestFiber().startFiber(10000); //new TestThread().startThread(10000); } }
2、ea-async:
https://github.com/electronicarts/ea-async
通过 Instrument 代码,提供 async-await 风格协程实现的工具
使用ea-async编写的代码,方法必须返回 CompletableFuture 或 CompletionStage
尝试
pom依赖
<dependency> <groupId>com.ea.async</groupId> <artifactId>ea-async</artifactId> <version>1.2.3</version> </dependency>
测试代码:
package constxiong.interview; import static com.ea.async.Async.await; import static java.util.concurrent.CompletableFuture.completedFuture; import java.util.concurrent.CompletableFuture; public class TestEaAsync { public static void main(String[] args) { String result = test().join(); System.out.println(result); System.out.println(testAsync()); } public static CompletableFuture<String> test() { return CompletableFuture.supplyAsync(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return "Hello"; }).thenCombine(CompletableFuture.supplyAsync(() -> { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return "ConstXiong"; }), (s1, s2) -> { return s1 + " " + s2; }); } public static String testAsync() { CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return "Hello"; }); CompletableFuture<String> cf2 = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return "ConstXiong"; }); return await(cf1) + " " +await(cf2); } }
参考:
- https://blog.csdn.net/guzhangyu12345/article/details/84666423
- https://www.open-open.com/lib/view/open1468892872350.html#articleHeader4
- https://zhuanlan.zhihu.com/p/36862142
- Java 自学指南
- Java 面试题汇总PC端浏览【点这里】
- Java知识图谱
- Java 面试题汇总小程序浏览,扫二维码
所有资源资源汇总于公众号