簡體   English   中英

Java同步死鎖?

[英]Java synchronized deadlock?

我對Java並發還很陌生,並且在嘗試使用鎖和監視器編寫玩具問題時陷入困境。 問題的要點是,我有一個具有getput方法的類,並且本質上是一個用於消費和產生線程的容器。 在我的生命中,我無法獲得正確的同步,並且最終會導致死鎖或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
    }
  }
}

有幾個問題:

  1. 您應該使用start on 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
    }
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM