scala同時プログラミング第二章練習問題
1
計算操作を実行する2つのコードブロックaおよびbを受信し、計算結果を含むメタグループを返し、署名するparallelという方法を実装する.
インプリメンテーション
2
時間を測定するためのパラメータdurationと計算操作を実行するコードブロックを受信すべきperiodicallyという方法を実装し、パラメータdurationが設定された期間が経過するたびに、コードブロックbを実行するスレッドを実行し、
インプリメンテーション
3
次のインタフェースを使用してSyncVarというクラスを実装します.
SyncVarの作成が完了したらNull値にし、getを呼び出して例外を投げ出し、putを呼び出して値を追加し、値を設定した後にgetが値を得、putが例外を投げ出す
4
前のオブジェクトを再実装し、オブジェクトでisEmptyとnonEmptyメソッドを実装し、さらに1つのメーカーと消費者を実装し、0-15デジタル伝達消費を行う
5
2つの方法を実装
残りは上記のようなもので、待機を実現するだけです.
6
複数値を格納するキューの実装
7
一括振替の実現
インプリメンテーション
8-9前の記事で言及したが、ここでは省略する.
scalaプロファイリングPriorityQueue,重み値の使用
計算操作を実行する2つのコードブロックaおよびbを受信し、計算結果を含むメタグループを返し、署名するparallelという方法を実装する.
def parallel[A,B](a: => A,b: =>B):(A,B)
インプリメンテーション
object Test1 extends App {
def parallel[A, B](a: => A, b: => B): (A, B) = {
var x = null.asInstanceOf[A]
var y = null.asInstanceOf[B]
new Thread{
override def run(): Unit ={
x = a
}
}.start()
new Thread{
override def run(): Unit ={
y = b
}
}.start()
(x,y)
}
}
2
時間を測定するためのパラメータdurationと計算操作を実行するコードブロックを受信すべきperiodicallyという方法を実装し、パラメータdurationが設定された期間が経過するたびに、コードブロックbを実行するスレッドを実行し、
def periodically(duraction:Long)(b: =>Unit):Unit
インプリメンテーション
/**
* Created by ctao on 2015/11/30.
*/
object Worker extends App{
def periodically(duration: Long)(b: => Unit): Unit = {
def work() = {
new Thread {
override def run(): Unit = {
b
Thread sleep duration
}
}.start()
}
while (true) {
work()
}
}
periodically(1000)(println("Hello"))
}
3
次のインタフェースを使用してSyncVarというクラスを実装します.
class SyncVar[T]{
def get():T = ???
def put(x:T):Unit = ???
}
SyncVarの作成が完了したらNull値にし、getを呼び出して例外を投げ出し、putを呼び出して値を追加し、値を設定した後にgetが値を得、putが例外を投げ出す
/**
* Created by ctao on 2015/11/30.
*/
class SyncVar[T] {
private var empty = false
private var value :T = null.asInstanceOf[T]
def get():T = this.synchronized{
if(empty){
throw new Exception("empty")
}else{
empty = false
value
}
}
def put(x:T):Unit = this.synchronized{
if(empty){
empty = false
value = x
}else{
throw new Exception("not empty")
}
}
}
4
前のオブジェクトを再実装し、オブジェクトでisEmptyとnonEmptyメソッドを実装し、さらに1つのメーカーと消費者を実装し、0-15デジタル伝達消費を行う
/**
* Created by ctao on 2015/11/30.
*/
class SyncVar2[T] {
private var empty = true
private var value:T = null.asInstanceOf[T]
def get():T = {
if(empty){
throw new Exception("empty")
}else{
empty = true
value
}
}
def isEmpty = this.synchronized(empty)
def nonEmpty = this.synchronized(!empty)
def put(x:T) = this.synchronized{
if(empty){
empty = false
value = x
}else{
throw new Exception("nonempty")
}
}
}
object TestSyncVar2 extends App{
val syncVar = new SyncVar2[Int]
new Thread{
override def run(): Unit ={
var x = 0
while(x <15){
if(syncVar.isEmpty){
syncVar.put(x)
x += 1
}
}
}
}.start()
new Thread{
override def run(): Unit ={
var x = 0
while(x != 15){
if(syncVar.nonEmpty){
println(syncVar.get())
x += 1
}
}
}
}.start()
}
5
2つの方法を実装
def getWait():T
def putWait(x:T):Unit
残りは上記のようなもので、待機を実現するだけです.
/**
* Created by ctao on 2015/11/30.
*/
class SyncVar3[T] {
private var empty = true
private var value:T = null.asInstanceOf[T]
def isEmpty = this.synchronized(empty)
def nonEmpty = this.synchronized(!empty)
def getWait:T = this.synchronized{
while(empty){
this.wait()
}
empty = true
value
}
def putWait(x:T):Unit = this.synchronized{
while (!empty){
this.wait()
}
empty = false
value = x
this.notify()
}
}
object TestSyncVar3 extends App{
val syncVar = new SyncVar3[Int]
new Thread{
override def run(): Unit ={
var x = 0
while(x <15){
if(syncVar.isEmpty){
syncVar.putWait(x)
x += 1
}
}
}
}.start()
new Thread{
override def run(): Unit ={
var x = 0
while(x != 15){
if(syncVar.nonEmpty){
println(syncVar.getWait)
x += 1
}
}
}
}.start()
}
6
複数値を格納するキューの実装
/**
* Created by ctao on 2015/11/30.
*/
class SyncQueue[T](val num:Int) {
private val syncQueue = collection.mutable.Queue[T]()
def getWait:T = this.synchronized {
while (syncQueue.isEmpty) {
this.wait()
}
val value = syncQueue.dequeue()
this.notify()
value
}
def putWait(x:T) = this.synchronized{
while(syncQueue.length == num){
this.wait()
}
syncQueue.enqueue(x)
this.notify()
}
}
object TestSyncQueue extends App{
val queue = new SyncQueue[Int](5)
new Thread{
override def run(): Unit ={
var x= 0
while(x<11){
queue.putWait(x)
x+=1
}
}
}.start()
new Thread{
override def run(): Unit ={
var x = 0
while(x<10){
x = queue.getWait
println(x)
}
}
}.start()
}
7
一括振替の実現
def sendAll(accounts:Set[Accout],target:Account):Unit
インプリメンテーション
/**
* Created by ctao on 2015/11/30.
*/
class Account(val name:String,var money:Int)
object AccountTest extends App{
def sendAll(accounts:Set[Account],target:Account):Unit = {
for(accountdef send(a:Account,b:Account,num:Int): Unit = this.synchronized{
println(s"${a.name} send $num to ${b.name} ,${a.money},${b.money}")
a.money -= num
b.money += num
println(a.money,b.money)
}
val a = new Account("a",10000)
val b = new Account("b",20000)
val c = new Account("c",30000)
val d = new Account("d",40000)
val e = new Account("e",50000)
val f = new Account("f",60000)
val g = new Account("g",0)
val sets = Set[Account](a,b,c,d,e,f)
sendAll(sets,g)
}
8-9前の記事で言及したが、ここでは省略する.
scalaプロファイリングPriorityQueue,重み値の使用