[英]Java synchronized deadlock?
我對Java並發還很陌生,並且在嘗試使用鎖和監視器編寫玩具問題時陷入困境。 問題的要點是,我有一個具有get
和put
方法的類,並且本質上是一個用於消費和產生線程的容器。 在我的生命中,我無法獲得正確的同步,並且最終會導致死鎖或IllegalMonitorStateException
。
package concurrency
object ThreadsMain extends App {
val syncVar = new SyncVar[Int]()
val producer = new Thread {
override def run(): Unit = {
for (x <- 1 to 15) {
syncVar.synchronized {
if (!syncVar.isEmpty) {
syncVar.wait()
} else {
syncVar.put(x)
syncVar.notify()
}
}
}
}
}
producer.run()
val consumer = new Thread {
this.setDaemon(true)
override def run(): Unit = {
while (true) {
syncVar.synchronized {
if (syncVar.isEmpty) {
syncVar.wait()
} else {
println(syncVar.get())
syncVar.notify()
}
}
}
}
}
consumer.run()
producer.join()
consumer.join()
}
class SyncVar[T]() {
var isEmpty: Boolean = true
var value: Option[T] = None
def get(): T = {
if (isEmpty) throw new Exception("Get from empty SyncVar")
else {
val toReturn = value.get
value = None
isEmpty = true
toReturn
}
}
def put(x: T): Unit = {
if (!isEmpty) throw new Exception("Put on non-empty SyncVar")
else {
value = Some(x)
isEmpty = false
}
}
}
有幾個問題:
start
on not run
。 join
,則沒有必要將踏步設置為守護線程。 if ... else
時,只會得到奇數。 它應該只是if
,其余后if
(實際上while
是一個更好的做法)。 我認為這種方式的代碼可以滿足您的需求:
object ThreadsMain extends App {
val syncVar = new SyncVar[Int]()
val isDone = new AtomicBoolean(false)
val producer = new Thread {
override def run(): Unit = {
for (x <- 1 to 15) {
syncVar.synchronized {
while (!syncVar.isEmpty) {
syncVar.wait()
}
syncVar.put(x)
syncVar.notify()
}
}
isDone.set(true)
}
}
producer.start()
val consumer = new Thread {
override def run(): Unit = {
while (!isDone.get()) {
syncVar.synchronized {
while (syncVar.isEmpty) {
syncVar.wait()
}
println(syncVar.get())
syncVar.notify()
}
}
}
}
consumer.start()
producer.join()
consumer.join()
}
class SyncVar[T]() {
var isEmpty: Boolean = true
var value: Option[T] = None
def get(): T = {
if (isEmpty) throw new Exception("Get from empty SyncVar")
else {
val toReturn = value.get
value = None
isEmpty = true
toReturn
}
}
def put(x: T): Unit = {
if (!isEmpty) throw new Exception("Put on non-empty SyncVar")
else {
value = Some(x)
isEmpty = false
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.