什么是协程?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);
    }

}

 

 

参考:

  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


 


 

所有资源资源汇总于公众号



 

 

posted @ 2019-12-05 19:51  ConstXiong  阅读(5093)  评论(0编辑  收藏  举报