我正在尝试熟悉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
但我不知道是什么。我正在使用一个ConditionVariable,这样我就可以在添加数据时向Consumer发出信号,但它似乎只能在第一次运行,之后生产者运行直到完成。我需要改变什么才能让它以消费者 - 生产者的方式运行,而不是以机器人工作者的方式运行? :)
答案 0 :(得分:4)
您的消费者在持有锁时必须await
(作为方法状态的javadocs)。
另外,您不应该使用tryLock
,您应该只使用lock
。如果您要进行其他,如果锁定获取失败,则仅使用tryLock
。在您的情况下,如果锁定获取失败,您只需尝试再次获取它。