2011-07-08 2 views
1

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を使用しているので、データが追加されたときにコンシューマーに信号を送ることができますが、初めて動作するように見えますが、その後はプロデューサが終了するまで実行されます。ロボット労働者のようなものではなく、消費者生産者のやり方で動かすためには、私は何を変える必要がありますか? :)

答えて

4

消費者はawaitであり、ロックを保持している間は(メソッド状態の場合はjavadocs)です。

また、tryLockを使用しないでください。ちょうどlockを使用する必要があります。 何か他のものをにする場合は、tryLockのみを使用します。あなたのケースでは、ロックの取得が失敗した場合は、もう一度それを取得しようとします。

+0

しかし、消費者がロックを保持するのを待っている場合、プロデューサはどのようにデータを追加できますか?プロデューサのtryLockは毎回falseを返しますか? – Senthess

+0

@Senthess - javadocsへのリンクが追加されています。 – jtahlborn

関連する問題