Search code examples
multithreadingscalaconcurrencyfuturearraybuffer

Use ArrayBuffer in sequentially executed Threads?


I have two Futures, the second of which starts after the first ended. Both write to the same ArrayBuffer instance, but since they are executed serially (not at the same time), I consider them not acting concurrently.

However, I know there is the @volatile annotation for variables shared among two or more threads (@volatile disables caching).

Since after the first thread finishes, inside the ArrayBuffer instance, there might be some caching going on that makes it impossible for the second thread to see the ArrayBuffer's real state: I am not sure whether it is safe to use ArrayBuffer this way.

Is it true that caching might be a problem in my situation, and if this is the case: Is there a recommended way to make ArrayBuffer use @volatile internally?


Solution

  • It should be fine iff (if-and-only-if) you propagate it [the array] through the future:

    val futureA = Future {
      val buf = ArrayBuffer(…)
      update(buf)
      buf
    }
    
    val futureB = futureA map {
      buf => moreUpdates(buf); buf
    }
    
    futureB foreach println // print the result of the transformations
    

    This is OK from a memory safety point of view because the completion of futureA happens-before the onComplete (virtually all transformations on Future is implemented on top of onComplete) callback is invoked. In this case map.