aguesuka
V2EX  ›  Java

用 Java 撸了一个 yield 的玩具

  •  2
     
  •   aguesuka · Sep 6, 2019 · 6296 views
    This topic created in 2615 days ago, the information mentioned may be changed or developed.

    效果如下

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

    16 replies  •  2019-09-07 22:03:12 +08:00
    optional
    optional
    Sep 6, 2019❤️1
    1
    vertx 欢迎你
    conn4575
    conn4575
    Sep 6, 2019 via Android
    2
    还是换语言吧,go 欢迎你😳
    nnegier
    nnegier
    Sep 6, 2019 via Android❤️1
    3
    kotlin 里面有协程,可能就是用的第一种增强字节码方式实现的,你可以反编译看看源码。我刚就在看 kotlin 开发 apk 反编译后的代码,还没懂,现在在吃饭。
    Soar360
    Soar360
    Sep 6, 2019 via iPhone
    4
    还是换语言吧 C# 欢迎你
    dobelee
    dobelee
    Sep 6, 2019 via Android
    5
    还是换语言吧 php 欢迎你
    linvaux
    linvaux
    Sep 6, 2019
    6
    还是换语言吧 Python 欢迎你
    jimrok
    jimrok
    Sep 6, 2019❤️1
    7
    java 12 的 Loom 项目,会考虑协程的引入。
    ZiLong
    ZiLong
    Sep 6, 2019❤️1
    8
    @jimrok Loom early-aeccessed ,应该快了
    gz911122
    gz911122
    Sep 6, 2019
    9
    kotlin 有协程
    GuuJiang
    GuuJiang
    Sep 7, 2019 via iPhone❤️1
    10
    可以参考下我自己撸的这个,就是用的第一种思路,并且完全不会破坏代码结构

    https://www.v2ex.com/t/459387
    imiao
    imiao
    Sep 7, 2019 via Android
    11
    还是换语言吧,C++欢迎你
    aguesuka
    aguesuka
    OP
    Sep 7, 2019 via Android
    12
    @GuuJiang 这个帖子我看过不少于 10 次
    qiyuey
    qiyuey
    Sep 7, 2019
    13
    Kotlin 欢迎你
    janxin
    janxin
    Sep 7, 2019
    14
    还是换语言吧,Javascript 欢迎你
    sagaxu
    sagaxu
    Sep 7, 2019 via Android
    15
    @nnegier kotlin 编译器帮你实现了一个状态机
    rb6221
    rb6221
    Sep 7, 2019
    16
    其实是有的 比如 github.com/esoco/coroutines
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   4983 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 46ms · UTC 07:00 · PVG 15:00 · LAX 23:00 · JFK 02:00
    ♥ Do have faith in what you're doing.