Java同步死锁?

我对 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

    }

  }

}



慕慕森
浏览 141回答 1
1回答

隔江千里

有几个问题:你应该使用starton not&nbsp;run。如果您正在使用join,则将踏面设置为守护线程是没有意义的。当您if ... else在生产商中进行操作时,您只会得到奇数。它应该只是if和其余的if(实际上while是一个更好的做法)。我认为这样代码可以满足您的需求:object ThreadsMain extends App {&nbsp; val syncVar = new SyncVar[Int]()&nbsp; val isDone = new AtomicBoolean(false)&nbsp; val producer = new Thread {&nbsp; &nbsp; override def run(): Unit = {&nbsp; &nbsp; &nbsp; for (x <- 1 to 15) {&nbsp; &nbsp; &nbsp; &nbsp; syncVar.synchronized {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (!syncVar.isEmpty) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; syncVar.wait()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; syncVar.put(x)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; syncVar.notify()&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; isDone.set(true)&nbsp; &nbsp; }&nbsp; }&nbsp; producer.start()&nbsp; val consumer = new Thread {&nbsp; &nbsp; override def run(): Unit = {&nbsp; &nbsp; &nbsp; while (!isDone.get()) {&nbsp; &nbsp; &nbsp; &nbsp; syncVar.synchronized {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (syncVar.isEmpty) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; syncVar.wait()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; println(syncVar.get())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; syncVar.notify()&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; }&nbsp; consumer.start()&nbsp; producer.join()&nbsp; consumer.join()}class SyncVar[T]() {&nbsp; var isEmpty: Boolean = true&nbsp; var value: Option[T] = None&nbsp; def get(): T = {&nbsp; &nbsp; if (isEmpty) throw new Exception("Get from empty SyncVar")&nbsp; &nbsp; else {&nbsp; &nbsp; &nbsp; val toReturn = value.get&nbsp; &nbsp; &nbsp; value = None&nbsp; &nbsp; &nbsp; isEmpty = true&nbsp; &nbsp; &nbsp; toReturn&nbsp; &nbsp; }&nbsp; }&nbsp; def put(x: T): Unit = {&nbsp; &nbsp; if (!isEmpty) throw new Exception("Put on non-empty SyncVar")&nbsp; &nbsp; else {&nbsp; &nbsp; &nbsp; value = Some(x)&nbsp; &nbsp; &nbsp; isEmpty = false&nbsp; &nbsp; }&nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java