java协程框架,
本文给大家带来了一些关于java的知识,主要整理了基于quasar实现协程池的相关问题。一个线程可以有多个协程,一个进程可以分别有多个协程。线程进程是同步机制,但是协程是异步的。下面就让我们一起来看看,希望对你有所帮助。
如何解决写爬虫IP受阻的问题?立即使用。
业务场景:golang和swoole都支持协同流程。在相同数量的并发任务下,协同进程可以比线程多几倍。所以最近在查询java的时候,了解到java本身没有协同学,但是有个牛自己实现了协同学,就是这篇文章的主角,quasar(纤体)!不过没看到有人公开手写协作池的骚操作(谁会直接用?那不是被社会打了嘛~)
一个线程可以有多个协程,一个进程可以分别有多个协程。
线程是同步机制,而协程是异步的。
进程可以保持上次调用的状态,每次进程重新进入,就相当于进入了上次调用的状态。
线程是可抢占的,而协程是不可抢占的,所以用户需要释放使用它们的权限来切换到其他协程。所以同一时间只有一个协程有权运行,相当于单线程的能力。
教练不是线程的替代品,是从线程中抽象出来的。线程是分开的CPU资源。教练是一个有组织的代码流。指导需要线程运行。线程是corching的资源,但corching并不直接使用线程。教练直接使用拦截器,拦截器可以关联任何线程或线程池,可以使当前线程,UI线程,或创建一个新的进程。
是线程协调的资源。进程通过拦截器间接使用线程资源。
废话不多说,直接上代码:
导入包:
属国
groupIdco.paralleluniverse/groupId
artifactIdquasar-core/artifactId
版本0 . 7 . 9/版本
分类器JDK 8/分类器
/dependencyWorkTools工具类:package com . example . ai;
进口公司parallel universe . fibers . fiber;
import co . parallel universe . fibers . suspend execution;
import co . parallel universe . strands . suspendablerunnable;
导入Java . util . concurrent . arrayblockingqueue;
公共类工作工具{
//协程池中协程的默认数量是5。
private static int WORK _ NUM=5;
//队列的默认任务是100
private static int TASK _ COUNT=100;
//工作协调数组
私有纤程[]工作线程;
//等待队列
private final ArrayBlockingQueueSuspendableRunnable task queue;
//用户在构建这个协同池时想要启动的协同数。
private final int workerNum
//构造方法:构建一个默认协同学数量的池。
公共工具(){
this(工作数量,任务数量);
}
//建立协同池,其中workNum为协同池中协同进程的数量。
公共工作工具(int workerNum,int taskCount) {
if (workerNum=0) {
workerNum=WORK _ NUM
}
if (taskCount=0) {
taskCount=任务计数;
}
this . worker num=worker num;
task queue=new ArrayBlockingQueue(task count);
workThreads=新纤程[worker num];
for(int I=0;我工作。i ) {
int finalI=I;
workThreads[i]=新纤程(new SuspendableRunnable() {
@覆盖
public void run()引发SuspendExecution,InterruptedException {
SuspendableRunnable runnable=null;
while (true){
尝试{
//获取任务,如果没有,则屏蔽。
runnable=task queue . take();
}catch(异常e){
system . out . println(e . getmessage());
}
//有任务就运行。
如果(runnable!=null){
runnable . run();
}
runnable=null
}
}
});//新建一个工做协程
工作线程[我].start();//启动工做协程
}
Runtime.getRuntime().可用处理器();
}
//执行任务,其实就是把任务加入任务队列,何时执行由协程池管理器决定
public void execute(SuspendableRunnable任务){
尝试{
任务队列。put(任务);//上传:阻塞接口的插入
} catch(异常e) {
//TODO:处理异常
System.out.println(阻塞);
}
}
//销毁协程池,该方法保证全部任务都完成的状况下才销毁全部协程,不然等待任务完成再销毁
public void destroy(){
//工做协程中止工做,且置为空
System.out.println(就绪关闭线程.);
for(int I=0;我工作我){
工作线程[I]=空;//帮助垃圾收集
}
任务队列。clear();//清空等待队列
}
//覆盖转换对象为字符串方法,返回协程信息:工做协程个数和已完成任务个数
@覆盖
公共字符串toString() {
返回工作线程号: workerNum ==分割线==等待任务号:任务队列。size();
}
}测试代码:
包com。举例。ai;
平行宇宙进口公司。股。suspendablerunnable
进口龙目岛SneakyThrows
导入org。spring框架。靴子。自动配置。弹簧启动应用程序;
导入Java。util。并发。countdownlatch
@SpringBootApplication
公共类应用程序{
@ SneakyThrows
公共静态void main(String[] args) {
//等待协程任务完毕后再结束主线程
CountDownLatch CDL=新CountDownLatch(50);
//开启5个协程,50个任务列队。
工作工具myThreadPool=新的工作工具(5,50);
for(int I=0;i 50i ){
int finalI=I;
myThreadPool.execute(新的SuspendableRunnable() {
@覆盖
公共无效运行(){
系统。出去。println(finalI);
尝试{
//延迟一秒
线程。睡眠(1000);
CDL。倒计时();
} catch (InterruptedException e) {
System.out.println(阻塞中);
}
}
});
}
//阻塞
CDL。await();
}
}
具体代码都有注释了,自行了解。我也是以线程池写法实现。
当前为解决问题:在协程阻塞过程中纤维类会报阻塞警告,满脸懵逼啊,看着很讨厌。暂时没有办法处理,看各位大神谁有招下方评论提供给下思路。万分感谢~
推荐学习: 《java视频教程》 以上就是实例介绍爪哇基于类星体实现协程池的详细内容,更多请关注我们其它相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。