Java同步死锁?
我对Java并发性非常陌生,我一直在试图用锁和监视器来解决一个小问题。问题的要点是我有一个类,它有Java同步死锁?,java,scala,Java,Scala,我对Java并发性非常陌生,我一直在试图用锁和监视器来解决一个小问题。问题的要点是我有一个类,它有get和put方法,本质上是线程消费和生成的容器。就我的一生而言,我无法正确地进行同步,结果要么死锁,要么出现IllegalMonitorStateException package concurrency object ThreadsMain extends App { val syncVar = new SyncVar[Int]() val producer = new Thread
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
}
}
}
包并发
对象线程在应用程序中扩展{
val syncVar=new syncVar[Int]()
val producer=新线程{
覆盖def run():单位={
对于(x有几个问题:
您应该在非run
上使用start
如果您使用的是join
,则没有必要将tread设置为守护进程线程
当你在制作人中做if…else
时,你只得到奇数。它应该是if
,其余的在if
之后(实际上而是一个更好的做法)
我认为通过这种方式,代码可以满足您的要求:
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
}
}
}
对象线程main扩展应用程序{
val syncVar=new syncVar[Int]()
val isDone=新原子布尔值(false)
val producer=新线程{
覆盖def run():单位={
对于(x多线程是最难编写的代码之一。你是Java新手吗?我建议不要使用这种低级Java 1.0结构。看看Java.util.concurrency和Executor类。它们是对臭名昭著的困难基类的改进。@duffymo我这么做纯粹是为了更好地理解高级Java 1.0结构是什么er级抽象正在幕后进行。这只是一个学习练习:)尝试调用start()而不是run()来实际启动线程。谢谢@rustyx!这让我松了一口气。也许在一个只有一个生产者和一个消费者的玩具示例中,你可以不受惩罚。但在现实生活中,将呼叫包装为在if中而不是在循环中等待会导致问题。请参阅