Я пытаюсь ознакомиться с классами 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)
}
}
Я пытаюсь создать 20 элементов в ListBuffer, а затем прочитать их. Я что-то упустил, потому что мой вывод выглядит примерно так:
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, чтобы я мог сигнализировать Потребителю, когда данные были добавлены, но кажется, что это работает только в первый раз, и после этого производитель работает, пока не закончится. Что мне нужно изменить, чтобы заставить его работать в режиме потребитель-производитель, а не в стиле робота? :)