什麼是協程?Java中如何支持?

協程(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);
    }

}

 

 

參考:

  1. https://blog.csdn.net/guzhangyu12345/article/details/84666423
  2. https://www.open-open.com/lib/view/open1468892872350.html#articleHeader4
  3. https://zhuanlan.zhihu.com/p/36862142


 


 

全部資源資源彙總於公衆號

 

相關文章
相關標籤/搜索