用 Java 撸了一个 yield 的玩具

2019-09-06 19:19:46 +08:00
 aguesuka

效果如下

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 能不能达到类似效果?

4875 次点击
所在节点    Java
16 条回复
optional
2019-09-06 19:22:20 +08:00
vertx 欢迎你
conn4575
2019-09-06 20:36:15 +08:00
还是换语言吧,go 欢迎你😳
nnegier
2019-09-06 20:57:23 +08:00
kotlin 里面有协程,可能就是用的第一种增强字节码方式实现的,你可以反编译看看源码。我刚就在看 kotlin 开发 apk 反编译后的代码,还没懂,现在在吃饭。
Soar360
2019-09-06 21:35:33 +08:00
还是换语言吧 C# 欢迎你
dobelee
2019-09-06 21:45:44 +08:00
还是换语言吧 php 欢迎你
linvaux
2019-09-06 21:50:14 +08:00
还是换语言吧 Python 欢迎你
jimrok
2019-09-06 21:58:09 +08:00
java 12 的 Loom 项目,会考虑协程的引入。
ZiLong
2019-09-06 22:47:47 +08:00
@jimrok Loom early-aeccessed ,应该快了
gz911122
2019-09-06 23:30:30 +08:00
kotlin 有协程
GuuJiang
2019-09-07 07:54:45 +08:00
可以参考下我自己撸的这个,就是用的第一种思路,并且完全不会破坏代码结构

https://www.v2ex.com/t/459387
imiao
2019-09-07 09:00:16 +08:00
还是换语言吧,C++欢迎你
aguesuka
2019-09-07 09:43:06 +08:00
@GuuJiang 这个帖子我看过不少于 10 次
qiyuey
2019-09-07 11:09:48 +08:00
Kotlin 欢迎你
janxin
2019-09-07 19:24:39 +08:00
还是换语言吧,Javascript 欢迎你
sagaxu
2019-09-07 21:30:54 +08:00
@nnegier kotlin 编译器帮你实现了一个状态机
janus77
2019-09-07 22:03:12 +08:00
其实是有的 比如 github.com/esoco/coroutines

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/598693

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX