1

ReentrantLock および ConditionVariable クラスに慣れようとしています。私はこのScalaコードを実装しました(「Scala固有」のものは何もありません):

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 個の要素を生成してから読み取ろうとしています。出力が次のようになる傾向があるため、何かが欠けています。

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

しかし、私は何を知りません。データが追加されたときに Consumer に通知できるように ConditionVariable を使用していますが、最初にしか機能しないようで、その後、プロデューサーは終了するまで実行されます。ロボットワーカーのような方法ではなく、コンシューマープロデューサーの方法で実行するには、何を変更する必要がありますか? :)

4

1 に答える 1

4

コンシューマーはawait 、ロックを保持している間(メソッド状態 のjavadocsとして)必要です。

また、を使用するべきではなくtryLock、単にを使用する必要がありますlock。ロックの取得が失敗した場合に何か他のtryLockことをする場合にのみ使用します。あなたの場合、ロックの取得が失敗した場合は、もう一度取得しようとします。

于 2011-07-08T12:32:36.327 に答える