false val t = new Thread(() => { println("thread: start") var i = 0 while (!stopRequested) { i += 1 } println("thread: finish") }) t.start() TimeUnit.SECONDS.sleep(1) println("stop request") stopRequested = true 17
= Thread.currentThread() var n = BigInt(1) try { while (!cancelled) { val f = fibonacci(n) println(f"fib($n) = $f") queue.put(f) // キューがいっぱいになるとブロックする n = n + BigInt(1) } } catch { case _: InterruptedException => println(" 割り込みが発生しました") } } 24
true thread.interrupt() // インタラプションを発生 } private def fibonacci(n: BigInt): BigInt = { if (n == BigInt(0) || n == BigInt(1)) n else { val a = n + BigInt(-2) val b = n + BigInt(-1) fibonacci(a) + fibonacci(b) } } } BlockingQueue#put はインタラプション発生時にブロックを解 除してくれるが、実装依存。一般的には実装されるべき。 25
var a: Int = 0; var b: Int = 0 def threadTest(testNo: Int) = { val startLatch = new CountDownLatch(1) x = 0; y = 0; a = 0; b = 0 val ta = new Thread({ () => startLatch.await() a = 1 x = b }) val tb = new Thread({ () => startLatch.await() b = 1 y = a }) ta.start(); tb.start() startLatch.countDown() ta.join(); tb.join() if (x == 0 && y == 0) { // 思い込みに反して (x, y) = (0, 0) が存在する println(s"t = $testNo, x = $x, y = $y") } } 32