队列的实现不是线程安全的

时间:2019-04-20 21:13:21

标签: multithreading scala

我正在尝试使用以整数排队的信号量来实现线程安全队列。目前,这不是线程安全的。在同步方面,我必须添加什么以使其成为线程安全的队列?

我尝试在队列上使用同步块,以便同时在队列中只允许一个线程,但这似乎不起作用,或者我滥用了它们。我应该同步什么?我有一个单独的类,该类不断通过维护线程进行附加和删除。

class ThreadSafeQueue {
    var queue = List[Int]()
    val semaphore = new Semaphore(0)

    def append(num: Int): Unit = {
        queue = queue ::: List(num)
        semaphore.release()
    }

    def dequeue(): Int = {
        semaphore.acquire()
        val n = queue.head
        queue = queue.tail
        n
    }
}

1 个答案:

答案 0 :(得分:1)

为确保线程安全,应将访问队列的代码放在synchronized块中,如下所示。

import java.util.concurrent.Semaphore

class ThreadSafeQueue {
  var queue = List[Int]()
  val semaphore = new Semaphore(0)

  def append(num: Int): Unit = {
    synchronized {
      queue = queue ::: List(num)
    }
    semaphore.release()
  }

  def dequeue(): Int = {
    semaphore.acquire()
    synchronized {
      val n = queue.head
      queue = queue.tail
      n
    }
  }
}

一些注意事项:

  1. Semaphore permits的值设置为0,所有acquire()的调用都将阻塞,直到出现release()

  2. 如果Semaphore permits的值> 0,则最好将方法dequeue修改为返回Option[Int],以解决使空队列出队的情况。

  3. 如果应用程序中只有一个队列,请考虑将ThreadSafeQueue定义为object ThreadSafeQueue

  4. 有一种使用AtomicReference进行原子安全的原子更新的有效方法。有关这两种方法之间的差异,请参见此SO link