This code is a simplification of other code that does useful things. To track progress of a loop, I am accumulating a volatile var count inside the loop and reporting the value of the count using a scheduled thread from Java concurrent.
def foo {
import java.util.concurrent._
@volatile var count = 0l
val reportRunner = new Runnable { def run() = println(s"report=$count") }
val scheduledExecutorService = Executors.newSingleThreadScheduledExecutor()
val reportRunnerHandle = scheduledExecutorService.scheduleAtFixedRate(reportRunner, 0,1000,TimeUnit.MILLISECONDS)
val l = Stream.fill(100000000)(0)
println(s"start count=$count")
for(i <- 0 until l.size) {
count = count + 1
}
println(s"end count=$count")
reportRunnerHandle.cancel(true)
scheduledExecutorService.shutdown()
}
It produced the following output for me:
report=0
start count=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=0
report=60019827
end count=100000000
Each of the report prints are suppose to occur every second but instead they occur in bursts and have the same count when they do. Feels like there is some fundamental JVM concurrency issue I am missing here. Or perhaps there are more reliable ways to do this besides ScheduledExecutorService?
Also not shown here, but I have tried this same code using AtomicLong and using Actors to accumulate the count instead of a volatile but I get the same results which makes me suspect the ScheduledExecutorService.