協程(Coroutine):是單線程下的併發,又稱微線程,纖程。簡單理解就是線程中的線程。html
優勢:java
輕量,建立成本小,下降了內存消耗git
用戶態調度,減小了 CPU 上下文切換的開銷,提升了 CPU 緩存命中率github
減小同步加鎖,提升了性能面試
能夠用同步思惟寫異步代碼編程
缺點:小程序
在協程執行中不能有阻塞操做,不然整個線程被阻塞緩存
不擅長處理 CPU 密集型併發
適用場景:異步
高性能要求,考慮犧牲公平性換取吞吐量
IO 密集型任務
Generator 式的流式計算
Java 官方目前是還沒推出協程
目前可用性比較高的有 Quasar 和 ea-async 兩個第三方庫,都是經過 byte code Instrument,把編譯後同步程序class文件修改成異步的操做。
一、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); } }
二、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); } }
參考: