15. volatileェ...
public class StopThread implements Runnable {
private volatile boolean terminate;
public void run() {
// (2) Volatile Load
while (! terminate) {
// スレッドで行う処理
}
}
public void setTerminate(boolean terminate) {
// (1) Volatile Store
this. terminate = terminate;
}
}
16. Q2.x,yの結果はどうなる?
x = 0; y = 0; a = 0; b = 0;
class AThread extend class BThread extend
Runnable { Runnable {
@Override @Override
public void run() { public void run() {
a = 1; b = 1;
x = b; y = a;
} }
} }
26. メッセージを受信するActor
class MyActor extends Actor {
def act() = { // Runnable#run相当
loop { // while(true)の簡略表現
receive { // メッセージの待ち受け(ブロックする)
case "end" => exit
case msg: String => println(msg)
}
}
}
}
val myactor = new MyActor
myactor.start()
// 文字列を渡す
myactor ! “Hello”
// 終了メッセージを渡す
myactor ! “end”
27. 返事を返すActor
val myactor = actor {
loop {
receive {
case "end" => exit
case "Hello" => reply("World")
}
}
}
// 戻り値を取得(返事が戻るまでブロック)
val result = myactor !? “Hello”
28. Futureを返すActor
val myactor = actor {
loop {
receive {
case "end" => exit
case numbers: List[Int] =>
重いソート処理
reply(result)
}
}
}
// futureパターン
val future = myactor !! largeNumbers
while(!future.isSet){ Thread.sleep(1000) }
val result = future()
29. もっと簡潔に
val myactor = actor {
loop {
receive {
case "end" => exit
case msg: String => println(msg)
}
}
}
// 文字列を渡す(ブロックしない)
myactor ! “Hello”
// 終了メッセージを渡す (ブロックしない)
myactor ! “end”
30. reactはスレッドを節約する
val myactor = actor {
loop {
react {
case "end" => exit
case numbers: List[Int] =>
重いソート処理
reply(result)
}
// 制御を返さないので,ここは実行できない
}
}
31. リソースを共有しない利点
class MyActor extends Actor {
def act() = { // Runnable#run相当
loop { // while(true)の簡略表現
receive { // メッセージの待ち受け(ブロックする)
case "end" => exit
case msg: String => println(msg)
}
}
}
} シングルスレッド脳
val myactor = new MyActor
myactor.start() で考えればよい
// 文字列を渡す
myactor ! “Hello”
// 終了メッセージを渡す
myactor ! “end”
32. mutalbleなメッセージはやめよう
class Money(var amount:BigDecimal, val actorA = new MyActor
var currency: Currency) {
def plus(add: Money):Unit = { val actorB = new MyActor
var a = amount val money = new Money(10,
a = a + add.amount
amount = a Currency.getInstance("JPY"
} ))
// いろいろ省略
actorA ! ("set", money)
} actorB ! ("set", money)
class MyActor extends Actor { actorA ! ("add", money)
var money: Money = _ actorB ! ("add", money)
def act() = {
loop {
react {
case "end" => exit
case ("set", m) => money = m
case ("add", m) =>
money.plus(m)
}
}
}
}
33. mutalbleなメッセージはやめよう
class Money(var amount:BigDecimal, val actorA = new MyActor
var currency: Currency) {
def plus(add: Money):Unit = { val actorB = new MyActor
var a = amount val money = new Money(10,
a = a + add.amount
amount = a Currency.getInstance("JPY"
} ))
// いろいろ省略
amount 参照の可視性
actorA ! ("set", money)
} actorB ! ("set", money)
plusメソッドの原子性
class MyActor extends Actor { actorA ! ("add", money)
var money: Money = _ actorB ! ("add", money)
def act() = {
loop {
react {
case "end" => exit
case ("set", m) => money = m
case ("add", m) =>
money.plus(m)
}
}
}
}
40. ロックで同期化
class Sequence {
private var value = 0
def getValue = value
// ↓ ロックが必要
def getAndIncrement() = synchronized {
value += 1
value
}
}
41. STM(Ref)
class Sequence {
private var value = Ref(0)
def getValue = value.get
def getAndIncrement() = atomic {
value alter (_ + 1)
}
}
class Ref[T] ...
def alter(f: T T): T = {
val value = f(get)
set(value)
value
}