2

I have to implement a blocking and synchronized queue in scala.

If I don't miss something, synchronizing is pretty simple, but for my queue to be blocking I could only think of that (which works) :

def pop() : T = {
    this.synchronized
    {
        _read()
        if(_out.isEmpty) throw new Empty()
        val ret = _out.head
        _out = _out.tail
        _length -= 1
        return ret
    }
}

def waitPop() : T =
{

    var ret : Option[T] = None

    // Possibly wait forever
    while(ret.isEmpty)
    {
        try { ret = Some(pop) }
        catch { case e : Empty => Thread.sleep(1000) }
    }

    ret.get
}

The problem here is Thread.sleep, it could compromise performance, couldn't it ? Of course, putting a lower value would mean consuming more of the CPU. Is there a way to wait properly ?

Thanks.

Théo Winterhalter
  • 4,908
  • 2
  • 18
  • 34

1 Answers1

1

Thanks to Voo, I got what I needed :

def waitPop() : T =
{
    this.synchronized
    {
        while(isEmpty) wait

        pop
    }
}

While in push, I added notifyAll (still in a synchronized block). notify was also working, but with notifyAll the result appears less deterministic.

Thanks a lot !

Théo Winterhalter
  • 4,908
  • 2
  • 18
  • 34
  • If you may block in `push` because you limit the size of the stack, then yes you need `notifyAll`, otherwise `notify` should be a bit more efficient because otherwise you wake up all threads although only one could do work. `notfiy` doesn't give any fairness guarantees though so yes that may be useful in some situations. – Voo Feb 24 '14 at 14:11
  • I also added this, because I have to make something the less deterministic possible (doesn't matter why I guess), with `notify`, I got all my thread get an element from the queue in the very same order I started them. – Théo Winterhalter Feb 24 '14 at 14:18