入门:java协程之quasar介绍
http://www.open-open.com/lib/view/open1468892872350.html
1、依赖:
<dependency>
<groupId>co.paralleluniverse</groupId>
<artifactId>quasar-core</artifactId>
<version>0.7.10</version>
<classifier>jdk8</classifier>
</dependency>
2、测试代码:
一、
static void doAll2(){
final IntChannel increasingToEcho = Channels.newIntChannel(10);
new Fiber<Void>(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
Thread.sleep(1000l);
increasingToEcho.send(0);
}
}).start();
test(increasingToEcho);
while (true){
}
}
static void test(IntChannel c){
try {
System.out.println("aa");
System.out.println(String.format("get %s",c.receive()));
System.out.println("dsd");
} catch (SuspendExecution suspendExecution) {
suspendExecution.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static public void main(String[] args) throws ExecutionException, InterruptedException, SuspendExecution, IOException {
doAll2();
}
结果:每次都会打印出get 0
2、
static void doAll2(){
final IntChannel increasingToEcho = Channels.newIntChannel(10);
new Fiber<Void>(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
Thread.sleep(1000l);
increasingToEcho.send(0);
}
}).start();
new Fiber<Void>(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
//test(increasingToEcho);
System.out.println("aa");
System.out.println(String.format("get %s",increasingToEcho.receive()));
}
}).start();
while (true){
}
}
static void test(IntChannel c){
try {
System.out.println("aa");
System.out.println(String.format("get %s",c.receive()));
System.out.println("dsd");
} catch (SuspendExecution suspendExecution) {
suspendExecution.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static public void main(String[] args) throws ExecutionException, InterruptedException, SuspendExecution, IOException {
doAll2();
}
结果:每次都会打印出 get 0
三、
static void doAll2(){
final IntChannel increasingToEcho = Channels.newIntChannel(10);
new Fiber<Void>(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
Thread.sleep(1000l);
increasingToEcho.send(0);
}
}).start();
new Fiber<Void>(new SuspendableRunnable() {
@Override
public void run() throws SuspendExecution, InterruptedException {
test(increasingToEcho);
}
}).start();
while (true){
}
}
static void test(IntChannel c){
try {
System.out.println("aa");
System.out.println(String.format("get %s",c.receive()));
System.out.println("dsd");
} catch (SuspendExecution suspendExecution) {
suspendExecution.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static public void main(String[] args) throws ExecutionException, InterruptedException, SuspendExecution, IOException {
doAll2();
}
结果:经常会打印不出get 0
原因分析:
1与3的区别是,1是在主线程中直接receive的,断点调试可以发现:
1在receive时将进入thread.yield,直到有数据而被唤醒:
而3
在该处会抛出SuspendExecution
但是2也会在该处抛出异常,为何2总是能够打印出get 0?
这就涉及到quasar的实现机制了,quasar compile的时候会改变所有throws SuspendExecution的方法,将该方法的签名改为包含上下文信息,可多次重入,在抛出SuspendExecution时会进行捕获,等到能够唤醒时重建上下文信息,并进行调用。
具体调用链路如下图所示:
详细地:
run以及restore的就是当前对象target: