为了账号安全,请及时绑定邮箱和手机立即绑定

Java同步死锁?

Java同步死锁?

慕慕森 2021-07-20 20:16:16
我对 Java 并发非常陌生,并且在尝试使用锁和监视器编写玩具问题时陷入困境。问题的要点是,我有一个具有get和put方法的类,并且本质上是线程消费和生产的容器。对于我的生活,我无法正确同步,最终会出现死锁或IllegalMonitorStateException.package concurrencyobject 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    }  }}
查看完整描述

1 回答

?
隔江千里

TA贡献1906条经验 获得超10个赞

有几个问题:

  1. 你应该使用starton not run

  2. 如果您正在使用join,则将踏面设置为守护线程是没有意义的。

  3. 当您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

    }

  }

}


查看完整回答
反对 回复 2021-07-29
  • 1 回答
  • 0 关注
  • 140 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信