Is there a FIFO stream in Scala?

后端 未结 3 880
野性不改
野性不改 2020-12-31 05:27

I\'m looking for a FIFO stream in Scala, i.e., something that provides the functionality of

  • immutable.Stream (a stream that can be finite and memorizes the ele
相关标签:
3条回答
  • 2020-12-31 06:01

    In Scala, streams are "functional iterators". People expect them to be pure (no side effects) and immutable. In you case, everytime you iterate on the stream you modify the queue (so it's no pure). This can create a lot of misunderstandings, because iterating twice the same stream, will have two different results.

    That being said, you should rather use Java BlockingQueues, rather than rolling your own implementation. They are considered well implemented in term of safety and performances. Here is the cleanest code I can think of (using your approach):

    import java.util.concurrent.BlockingQueue
    import scala.collection.JavaConversions._
    
    class FIFOStream[A]( private val queue: BlockingQueue[Option[A]] ) {
      def toStream: Stream[A] = queue take match {
        case Some(a) => Stream cons ( a, toStream )
        case None => Stream empty
      }
      def close() = queue add None
      def enqueue( as: A* ) = queue addAll as.map( Some(_) )
    }
    
    object FIFOStream {
      def apply[A]() = new LinkedBlockingQueue
    }
    
    0 讨论(0)
  • 2020-12-31 06:03

    I'm assuming you're looking for something like java.util.concurrent.BlockingQueue?

    Akka has a BoundedBlockingQueue implementation of this interface. There are of course the implementations available in java.util.concurrent.

    You might also consider using Akka's actors for whatever it is you are doing. Use Actors to be notified or pushed a new event or message instead of pulling.

    0 讨论(0)
  • 2020-12-31 06:03

    1) It seems you're looking for a dataflow stream seen in languages like Oz, which supports the producer-consumer pattern. Such a collection is not available in the collections API, but you could always create one yourself.

    2) The data flow stream relies on the concept of single-assignment variables (such that they don't have to be initialized upon declaration point and reading them prior to initialization causes blocking):

    val x: Int
    startThread {
      println(x)
    }
    println("The other thread waits for the x to be assigned")
    x = 1
    

    It would be straightforward to implement such a stream if single-assignment (or dataflow) variables were supported in the language (see the link). Since they are not a part of Scala, you have to use the wait-synchronized-notify pattern just like you did.

    Concurrent queues from Java can be used to achieve that as well, as the other user suggested.

    0 讨论(0)
提交回复
热议问题