Project LoomでJavaでの継続(Continuation)を試す

Project Loomは、Javaで継続(Continuation)やFiber(軽量スレッド)、末尾呼び出し最適化なんかを実現するプロジェクトです。
OpenJDK: Loom


そのLoom、ながいことどうやって動かすかもよくわからない感じだったのが、先日のJVMLSにあわせてプロトタイプが公開されてました。
http://mail.openjdk.java.net/pipermail/loom-dev/2018-July/000061.html


ビルド方法はこんな感じです。

$ hg clone http://hg.openjdk.java.net/loom/loom  
$ cd loom  
$ hg update -r fibers 
$ sh configure   
$ make images

たりないパッケージはconfigureのときに教えてくれるので、それに従って入れていけばいいです。


Continuationはプログラムを動かしたり止めたりの制御ができる仕組みです。

public class LoomSample {
  public static void main(String... args) {
    var scope = new ContinuationScope() {};
    var c = new Continuation(scope, () -> {
      System.out.println("c1");
      Continuation.yield(scope);
      System.out.println("c2");
      Continuation.yield(scope);
      System.out.println("c3");
    });
    System.out.println("out1");
    c.run();
    System.out.println("out2");
    c.run();
    System.out.println("out3");
    c.run();
    System.out.println("out4");
  }
}

Continuation#yieldで動きを止めて、run()で再開できる感じ。
実行するとこういう出力になります。

out1
c1
out2
c2
out3
c3
out4


Fiberは、このContinuationにスケジューラを組み合わせて並行実行する感じになります。


で、たとえばゲームなどで、異なる動きをするキャラクタを1/60ごとに1フレーム動かすみたいな処理は自分で状態機械を組んだり面倒なコードが必要になります。継続で書ければ、それぞれの動きを通常の処理として書けばいいことになります。


往復運動する青い四角と、円運動する赤い丸を1/20秒ごとに動かすというサンプルを書いてみました。
https://gist.github.com/kishida/3898fdc50757e8d66a2f1f79f6d378db


結構いい感じに動いてます。


Loomの資料は、wikiがここにあって、JVMLS2018の資料なども公開されています。
https://wiki.openjdk.java.net/display/loom/Main


目的みたいなことは、ここでまとまってます。
Loom Proposal.md


Fiberは、伊藤さんがechoサーバーつくってます
https://github.com/chiroito/sandbox/blob/master/sandbox-loom/src/main/java/FiberEchoServer.java