10

Click here to load reader

Quasar: Actor Model and Light Weight Threads on Java

Embed Size (px)

Citation preview

Page 1: Quasar: Actor Model and Light Weight Threads on Java

Quasar: Java のアクター/軽量スレッド

宮川 拓 / @miyakawa_taku

2014-08-22

JJUG LT大会

Page 2: Quasar: Actor Model and Light Weight Threads on Java

自己紹介

• 宮川拓です

• Kink という JVM 言語を作ってます

– https://bitbucket.org/kink/kink

• 大相撲秋場所に向けて準備中です

1

Page 3: Quasar: Actor Model and Light Weight Threads on Java

Quasar?

• Erlang 的なアクターモデルを実現する Java ライブラリ

2

Page 4: Quasar: Actor Model and Light Weight Threads on Java

アクターモデル

• アクター(スレッド的なもの)同士がメッセージを互いに投げ合って協調動作する計算モデル

• オブジェクトを作る感覚でアクターを作る

• つまり湯水のごとくスレッドを作る

3

Page 5: Quasar: Actor Model and Light Weight Threads on Java

Scala のアクターと何が違うの?

• Scala のアクター

–ネイティブスレッドで実現されている

• Quasar のアクター

–軽量スレッドで実現されている

4

Page 6: Quasar: Actor Model and Light Weight Threads on Java

軽量スレッド?

• 軽量スレッド ::=

–ユーザランド(カーネル外)で実現するスレッド

– Go の goroutine, Erlang の「プロセス」など

– Quasar では「Fiber」と呼ぶ

• 利点

– 100万とか1,000万とかの数が作れる

–ブロックが多発する状況では性能で有利

5

Page 7: Quasar: Actor Model and Light Weight Threads on Java

実現方法

• バイトコード操作でコンテキストスイッチ用のコードを仕込む

– クラスロード時(-javaagent) or コンパイル時

6

Page 8: Quasar: Actor Model and Light Weight Threads on Java

実行時の動作

1. 実行している命令の位置

2. ローカル変数のセット

を自前のスタックに保存しながら実行する (ようにバイトコードを改変する)

7

class SenderFiber extends Fiber { public Void run() throws ... { int num = 42; channel.send(num); num = 24; channel.send(num); bye(); } }

data=24

Page 9: Quasar: Actor Model and Light Weight Threads on Java

制御が離れる時の動作

• ブロック/yieldするメソッドがSuspendExecution例外を投げる

• 呼び出し元がキャッチして他の軽量スレッドに制御を渡す

8

class SenderFiber extends Fiber { public Void run() throws ... { int num = 42; channel.send(num); num = 24; channel.send(num); bye(); } }

SuspendExecution

Page 10: Quasar: Actor Model and Light Weight Threads on Java

制御が戻ってくる時の動作

• もう一度同じメソッドを呼び出す

• メソッドの先頭で自前スタックから実行位置とローカル変数を回復

• switch & ジャンプ

9

class SenderFiber extends Fiber { public Void run() throws ... { int num = 42; channel.send(num); num = 24; channel.send(num); bye(); } }

ローカル変数回復 switch & ジャンプ