当前位置:

首页 > 编程开发 > 如何使用Quasar实现Java协程池?

如何使用Quasar实现Java协程池?

业务场景:golang与swoole都拥抱了协程,在同任务并发数量下,协程可比线程多几倍。所以最近在查询java时了解java本身是没有协程的,但是某牛自行实现了协程,也就是本文的主角quasar(纤程)!不过没看到谁公开一下手写协程池的骚操作(谁会直接new它用?那是没挨过社会的毒打呀~)一个线程可以多个协程,一个进程也可以单独拥有多个协程。线程进程都是同步机制,而协程则是异步。协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态。线程是抢占式,而协程是非抢占式的,所以需要用户自己

本文目录

    如何使用Quasar实现Java协程池?

    业务场景:golang与swoole都拥抱了协程,在同任务并发数量下,协程可比线程多几倍。所以最近在查询java时了解java本身是没有协程的,但是某牛自行实现了协程,也就是本文的主角quasar(纤程)!不过没看到谁公开一下手写协程池的骚操作(谁会直接new它用?那是没挨过社会的毒打呀~)

    一个线程可以多个协程,一个进程也可以单独拥有多个协程。

    线程进程都是同步机制,而协程则是异步。

    协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态。

    线程是抢占式,而协程是非抢占式的,所以需要用户自己释放使用权来切换到其他协程,因此同一时间其实只有一个协程拥有运行权,相当于单线程的能力。

    协程并不是取代线程, 而且抽象于线程之上, 线程是被分割的CPU资源, 协程是组织好的代码流程, 协程需要线程来承载运行, 线程是协程的资源, 但协程不会直接使用线程, 协程直接利用的是执行器(Interceptor), 执行器可以关联任意线程或线程池, 可以使当前线程, UI线程, 或新建新程.。

    线程是协程的资源。协程通过Interceptor来间接使用线程这个资源。

    如何使用Quasar实现Java协程池?

    废话不多说,直接上代码:

    导入包:

            
                co.paralleluniverse
                quasar-core
                0.7.9
                jdk8
            
    WorkTools工具类:
    package com.example.ai;
    
    import co.paralleluniverse.fibers.Fiber;
    import co.paralleluniverse.fibers.SuspendExecution;
    import co.paralleluniverse.strands.SuspendableRunnable;
    
    import java.util.concurrent.ArrayBlockingQueue;
    
    
    public class WorkTools {
        //协程池中默认协程的个数为5
        private static int WORK_NUM = 5;
        //队列默认任务为100
        private static int TASK_COUNT = 100;
    
        //工做协程数组
        private Fiber[] workThreads;
        //等待队列
        private final ArrayBlockingQueue taskQueue;
    
        //用户在构造这个协程池时,但愿启动的协程数
        private final int workerNum;
    
    
        //构造方法:建立具备默认协程个数的协程池
        public WorkTools() {
            this(WORK_NUM,TASK_COUNT);
        }
    
        //建立协程池,workNum为协程池中工做协程的个数
        public WorkTools(int workerNum, int taskCount) {
            if (workerNum <= 0) {
                workerNum = WORK_NUM;
            }
            if (taskCount <= 0) {
                taskCount = TASK_COUNT;
            }
            this.workerNum = workerNum;
            taskQueue = new ArrayBlockingQueue(taskCount);
            workThreads = new Fiber[workerNum];
            for (int i = 0; i < workerNum; i++) {
                int finalI = i;
                workThreads[i] = new Fiber<>(new SuspendableRunnable() {
                    @Override
                    public void run() throws SuspendExecution, InterruptedException {
                        SuspendableRunnable runnable = null;
                        while (true){
                            try{
                                //取任务,没有则阻塞。
                                runnable = taskQueue.take();
                            }catch (Exception e){
                                System.out.println(e.getMessage());
                            }
                            //存在任务则运行。
                            if(runnable != null){
                                runnable.run();
                            }
    
                            runnable = null;
                        }
                    }
                });  //new一个工做协程
    
                workThreads[i].start();  //启动工做协程
    
            }
    
            Runtime.getRuntime().availableProcessors();
        }
        //执行任务,其实就是把任务加入任务队列,何时执行由协程池管理器决定
        public void execute(SuspendableRunnable task) {
            try {
                taskQueue.put(task);   //put:阻塞接口的插入
            } catch (Exception e) {
                // TODO: handle exception
                System.out.println("阻塞");
            }
        }
        //销毁协程池,该方法保证全部任务都完成的状况下才销毁全部协程,不然等待任务完成再销毁
        public void destory() {
            //工做协程中止工做,且置为null
            System.out.println("ready close thread...");
            for (int i = 0; i < workerNum; i++) {
    
                workThreads[i] = null; //help gc
            }
            taskQueue.clear();  //清空等待队列
        }
        //覆盖toString方法,返回协程信息:工做协程个数和已完成任务个数
        @Override
        public String toString() {
            return "WorkThread number:" + workerNum + " ==分割线== wait task number:" + taskQueue.size();
        }
    }

    测试代码:

    package com.example.ai;
    
    import co.paralleluniverse.strands.SuspendableRunnable;
    import lombok.SneakyThrows;
    
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    import java.util.concurrent.CountDownLatch;
    
    
    
    @SpringBootApplication
    
    
    public class AiApplication {
    
        @SneakyThrows
        public static void main(String[] args) {
            //等待协程任务完毕后再结束主线程
            CountDownLatch cdl = new CountDownLatch(50);
            //开启5个协程,50个任务列队。
            WorkTools myThreadPool = new WorkTools(5, 50);
            for (int i = 0; i< 50; i++){
                int finalI = i;
                myThreadPool.execute(new SuspendableRunnable() {
                    @Override
                    public void run() {
                        System.out.println(finalI);
                        try {
                            //延迟1秒
                            Thread.sleep(1000);
                            cdl.countDown();
                        } catch (InterruptedException e) {
                            System.out.println("阻塞中");
                        }
                    }
                });
    
            }
            //阻塞
            cdl.await();
        }
    
    }

    如何使用Quasar实现Java协程池?

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Java
    相关文章 更多
    Java单元测试入门:使用JUnit 5编写第一个测试用例
    Java单元测试入门:使用JUnit 5编写第一个测试用例

    面向初学者的JUnit 5实用入门指南。从测试概念、Maven依赖配置,到手把手编写首个单元测试用例及断言验证,助你掌握Java单元测试的核心流程。

    Java变量未初始化报错解析:局部变量与成员变量默认值差异
    Java变量未初始化报错解析:局部变量与成员变量默认值差异

    深入解析Java中局部变量未初始化编译报错与成员变量自动赋予默认值的机制差异,涵盖JVM内存分配、编译期确定性赋值检查与实际排查修复方案。

    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat
    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat

    详细讲解在Java中获取当前系统时间并进行格式化输出的两种核心方案:基于Java 8全新日期时间API的DateTimeFormatter与传统遗留的SimpleDateFormat,包含完整代码示例、线程安全机制对比及生产选型建议。

    Java中final与static final常量的定义及初始化规则
    Java中final与static final常量的定义及初始化规则

    深入解析Java中final变量与static final常量的定义、内存语义、初始化时机及合法赋值路径,涵盖编译期常量优化与实战避坑指南。

    Java抽象方法与接口方法的区别及选型建议
    Java抽象方法与接口方法的区别及选型建议

    深入对比Java中抽象类抽象方法与接口方法的语法演进、设计意图及运行期差异,并提供清晰的架构选型决策流程与实战范例。

    Java实现HTTP请求与JSON解析的完整代码示例
    Java实现HTTP请求与JSON解析的完整代码示例

    本文提供Java标准库HttpClient发起HTTP GET/POST请求并结合Jackson进行JSON数据反序列化与序列化的完整代码示例与工程实践指南。

    Java递归出现StackOverflowError的原因分析及栈空间优化方案
    Java递归出现StackOverflowError的原因分析及栈空间优化方案

    详细分析Java递归调用出现StackOverflowError的原因,结合代码说明线程栈、栈帧和递归深度之间的关系,并介绍终止条件排查、迭代改写、减少栈帧开销以及通过-Xss调整JVM栈空间的方法。

    Java空指针异常(NPE)的代码排查与修复实例
    Java空指针异常(NPE)的代码排查与修复实例

    针对Java中常见的NullPointerException(NPE),本文从堆栈日志定位、典型代码触发场景、具体修复代码对比到防御体系进行系统讲解,提供实用且易上手的排查与修复方案。

    selenium上传文件教程本地文件路径设置方法
    selenium上传文件教程本地文件路径设置方法

    深入解析Selenium处理文件上传的技术细节,涵盖标准HTML控件的路径直接注入法与非标准控件的系统级模拟方案,提供Windows与Linux环境下的路径设置最佳实践及常见异常排查。

    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景
    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景

    针对大数据工程场景,系统对比Java、Scala与Python在执行性能、生态结合、开发效率和维护成本上的核心差异,给出清晰的架构选型依据与落地方案。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。