在Java中使用协程(Coroutine)
来源:互联网 发布:雨人软件科技有限公司 编辑:程序博客网 时间:2024/04/30 12:51
各种语言在实现Coroutine方式的支持时,多数都采用了Actor Model来实现,Actor Model简单来说就是每个任务就是一个Actor,Actor之间通过消息传递的方式来进行交互,而不采用共享的方式,Actor可以看做是一个轻量级的进程或线程,通常在一台4G内存的机器上,创建几十万个Actor是毫无问题的。
对于Java应用而言,传统方式下为了支持高并发,由于一个线程只能用于处理一个请求,即使是线程中其实有很多IO中断、锁等待也同样如此,因此通常的做法是通过启动很多的线程来支撑高并发,但当线程过多时,就造成了CPU需要消耗不少的时间在线程的切换上,从而出现瓶颈,按照上面对Coroutine的描述,Coroutine的方式理论上而言能够大幅度的提升Java应用所能支撑的并发量。
Kilim是由剑桥的两位博士开发的一个用于在Java中使用Coroutine的框架,Kilim基于Java语法,先来看看Kilim中的关键概念。
l Task
可以认为Task就是Actor,使用方式和Java Thread基本相同,只是继承的为Task,覆盖的为execute方法,启动也是调用task的start方法。
l Task的消息发送机制
Kilim中通过Mailbox对象来发送消息,Mailbox的基本原则为可以有多个消息发送者,但只能有一个消息接收者,发送的方式有同步发送、异步发送和阻塞线程方式的同步发送三种,同步发送是指保证一定能将消息放入发送队列中,如当前发送队列已满,则等待到可用为止,阻塞的为当前Task;异步发送则是尝试将消息放入发送队列一次,如失败,则返回false,成功则返回true,不会阻塞Task;阻塞线程方式的同步发送是指阻塞当前线程,并保证将消息发送给接收者,三种方式的使用方法如下:
mailbox.put(messageObject); // 同步发送
mailbox.putnb(messageObject); // 异步发送
mailbox.putb(messageObject); // 阻塞线程方式发送
l Task的消息接收机制
Kilim中通过Mailbox来接收消息,接收消息的方式有同步接收、异步接收以及阻塞线程方式的同步接收三种,同步接收是指阻塞当前Task,直到接收到消息才返回;异步接收是指立刻返回Mailbox中的消息,有就返回,没有则返回null;阻塞线程方式的同步接收是指阻塞当前线程,直到接收到消息才返回,使用方法如下:
mailbox.get(); // 同步接收,传入long参数表示等待的超时时间,单位为毫秒
mailbox.getnb(); // 异步接收,立刻返回
mailbox.getb(); // 阻塞线程方式接收
在实际Java应用中使用Coroutine时,通常会出现以下几种典型的更复杂的使用场景,由于Actor模式本身就是异步的,因此其天然对异步场景支持的就非常好。
在Kilim中要实现Task之间的同步调用非常简单,代码如下:
- public class TaskA extends Task{
- public void execute() throws Pausable,Exception{
- Mailbox<Object> result=new Mailbox<Object>();
- Task task=new TaskB(result);
- task.start();
- Object resultObject=result.get();
- System.out.println(resultObject);
- }
- }
- public class TaskB extends Task{
- private Mailbox<Object> result;
- public TaskB(Mailbox<Object> result){
- this.result=result;
- }
- public void execute() throws Pausable,Exception{
- result.put(“result from TaskB”);
- }
- }
public class TaskA extends Task{ public void execute() throws Pausable,Exception{ Mailbox<Object> result=new Mailbox<Object>();Task task=new TaskB(result); task.start(); Object resultObject=result.get(); System.out.println(resultObject);}}public class TaskB extends Task{ private Mailbox<Object> result;public TaskB(Mailbox<Object> result){ this.result=result;}public void execute() throws Pausable,Exception{ result.put(“result from TaskB”);}}Kilim的Mailbox.get并不会阻塞线程,因此这种方式是完全满足需求的。
- 在Java中使用协程(Coroutine)
- 在Java中使用协程(Coroutine)
- 在Java中使用协程(Coroutine)
- 在 Android 中使用协程(Coroutine)
- [Unity3D]Lua中使用协程coroutine和计时器timer
- [Unity3D]Lua中使用协程coroutine和计时器timer
- Unity引擎在执行协程(Coroutine)的原理
- 关于Unity3D的协程(Coroutine)
- 关于Unity3D的协程(Coroutine)
- 关于Unity3D的协程(Coroutine)
- 关于Unity3D的协程(Coroutine)
- 详解Unity3D中的协程(Coroutine)
- 关于Unity3D的协程(Coroutine)
- 说说协程coroutine
- Unity如何在Editor下执行协程(coroutine)
- Unity如何在Editor下执行协程(coroutine)
- libcoro:在c++中支持coroutine
- Unity3D之协程Coroutine
- Android基础组件-ContentProvider(二)
- PageRank算法
- 二分查找:Search for a Range
- CheckStyle的检查规则(共138条规则)
- poj 3140 Contestants Division DFS
- 在Java中使用协程(Coroutine)
- 11个EL隐式对象
- 22、C#:利用接口增加封装安全性
- 第二章:java_基本语法_3 运算符
- redis配置认证密码
- git 使用笔记
- JVM:如何分析线程堆栈
- MFC指示灯学习
- Javascript 面向对象编程(一):封装