ReentrantLockクラスとConditionVariableクラスをよく理解しています。この「あまり同期していない」コンシューマプロデューサの例を修正するには
object Conditioned {
var pops = 0
var max = 20
abstract class NamedThread extends Thread {
def myName = this.toString
}
class Producer(lock:Lock,condition:Condition,source:ListBuffer[Int]) extends NamedThread {
override def run = {
var number = max
var current = 0
while(current < number)
{
if(lock.tryLock)
{
try
{
current += 1
source += current
println("producer added data:"+current)
condition.signal
} finally {
lock.unlock
Thread.sleep(100)
}
}
}
}
}
class Consumer(lock:Lock,condition:Condition,source:ListBuffer[Int]) extends NamedThread {
override def run = {
while(pops < max) {
println("awaiting")
while(source.isEmpty)
condition.await
println("consumer try lock")
if(lock.tryLock)
{
try {
val data = source(source.size - 1)
source -= data
println("consumer received data:"+data+" hello from:"+myName)
pops += 1
} finally { lock.unlock }
}
}
}
}
def main(args:Array[String]) = {
val lock = new ReentrantLock
val condition = lock.newCondition
var lb = new collection.mutable.ListBuffer[Int]()
val producer = new Producer(lock,condition,lb)
val consumer = new Consumer(lock,condition,lb)
val cons2 = new Consumer(lock,condition,lb)
val threads = Array(producer,consumer,cons2)
threads.foreach(_.start)
threads.foreach(_.join)
}
}
私はListBufferで20個の要素を生成しようとし、それらを読んでいます:私は(その中に「Scalaの特定」何もせずに)、このScalaのコードを実装しました。私の出力は次のようになる傾向があるため、何かが欠けています。
awaiting
consumer try lock
producer added data:1
awaiting
consumer try lock
consumer received data:1 hello from:Thread[Thread-51,5,trap.exit]
awaiting
awaiting
producer added data:2
producer added data:3
producer added data:4
producer added data:5
producer added data:6
producer added data:7
producer added data:8
producer added data:9
producer added data:10
producer added data:11
producer added data:12
producer added data:13
producer added data:14
producer added data:15
producer added data:16
producer added data:17
producer added data:18
producer added data:19
producer added data:20
私は何が分かりません。私はConditionVariableを使用しているので、データが追加されたときにコンシューマーに信号を送ることができますが、初めて動作するように見えますが、その後はプロデューサが終了するまで実行されます。ロボット労働者のようなものではなく、消費者生産者のやり方で動かすためには、私は何を変える必要がありますか? :)
しかし、消費者がロックを保持するのを待っている場合、プロデューサはどのようにデータを追加できますか?プロデューサのtryLockは毎回falseを返しますか? – Senthess
@Senthess - javadocsへのリンクが追加されています。 – jtahlborn