效果如下
public class GeneratorTest { private int a = 0; private int b = 1; @Test public void test2() { Generator<Integer> generator = new Generator<>(); generator.loop() .and(() -> a += b) .and(y -> y.yield(b)) .and(() -> b += a) .until(y -> y.yieldIf(b > 1000).yieldBreak().yieldElse().yield(a)); for (Integer result : generator) { System.out.print("result = " + result); System.out.print(" a = " + a); System.out.println(" b = " + b); } } }
运行结果
result = 1 a = 1 b = 1 result = 1 a = 1 b = 2 result = 2 a = 3 b = 2 result = 3 a = 3 b = 5 result = 5 a = 8 b = 5 result = 8 a = 8 b = 13 result = 13 a = 21 b = 13 result = 21 a = 21 b = 34 result = 34 a = 55 b = 34 result = 55 a = 55 b = 89 result = 89 a = 144 b = 89 result = 144 a = 144 b = 233 result = 233 a = 377 b = 233 result = 377 a = 377 b = 610
之前把另一个项目某模块从 bio 改成了 nio,尝到了协程的甜头,宽带可以跑满,基本不占 cpu.于是打算把剩余的模块改完.结果发现连接状态一多,handler 就会越来越长,如果还有条件和循环,那就几乎没法写了.于是我就想 java 如果有 yield 就好了.
目前实现 yield 的方法有三种,第一种是改字节码,但是比想象中麻烦,第二种是返回一个阻塞队列,yield()是阻塞方法,将结果用其他线程返回,但是涉及到多线程,而原来的目的就是像把项目改成协程的.所以就用了第三种,把需要 yield 的代码块当成 lambda,传入链表中依次调用,如果调用了参数的 yield 的方法就返回一次结果;
做完以后感觉自己走了弯路.java 有没有类似的包或者工具?用 stream 能不能达到类似效果?
1 optional 2019-09-06 19:22:20 +08:00 ![]() vertx 欢迎你 |
2 conn4575 2019-09-06 20:36:15 +08:00 via Android 还是换语言吧,go 欢迎你 |
3 nnegier 2019-09-06 20:57:23 +08:00 via Android ![]() kotlin 里面有协程,可能就是用的第一种增强字节码方式实现的,你可以反编译看看源码。我刚就在看 kotlin 开发 apk 反编译后的代码,还没懂,现在在吃饭。 |
![]() | 4 Soar360 2019-09-06 21:35:33 +08:00 via iPhone 还是换语言吧 C# 欢迎你 |
5 dobelee 2019-09-06 21:45:44 +08:00 via Android 还是换语言吧 php 欢迎你 |
![]() | 6 linvaux 2019-09-06 21:50:14 +08:00 还是换语言吧 Python 欢迎你 |
![]() | 7 jimrok 2019-09-06 21:58:09 +08:00 ![]() java 12 的 Loom 项目,会考虑协程的引入。 |
![]() | 9 gz911122 2019-09-06 23:30:30 +08:00 kotlin 有协程 |
![]() | 11 imiao 2019-09-07 09:00:16 +08:00 via Android 还是换语言吧,C++欢迎你 |
![]() | 13 qiyuey 2019-09-07 11:09:48 +08:00 Kotlin 欢迎你 |
![]() | 14 janxin 2019-09-07 19:24:39 +08:00 还是换语言吧,Javascript 欢迎你 |
![]() | 16 rb6221 2019-09-07 22:03:12 +08:00 其实是有的 比如 github.com/esoco/coroutines |