问题
import scala.sys.process._
import scala.concurrent._ // (future)
import ExecutionContext.Implicits.global // (future)
/* run "ls /opt"
* which outputs 2 lines:
* - "X11"
* - "local"
*/
val command = Process(Seq("ls", "/opt"), None, "LANG" -> "")
val process = command.run(ProcessLogger(line => {
Thread.sleep(1000) // slow execution down
println(Thread.currentThread)
println(line)
println("")
}))
Future {
process.exitValue // blocks until the process exits
}.onComplete { results =>
println(Thread.currentThread)
println("process exited: after last line callback finished?")
println("DONE")
}
Output (order as expected, but is this always the case?):
Thread[Thread-47,5,run-main-group-0]
LINE X11
Thread[Thread-47,5,run-main-group-0]
LINE local
Thread[ForkJoinPool-1-worker-3,5,run-main-group-0]
process exited: after last line callback finished?
DONE
It seems o.k. because the onComplete
block outputs its text after line-related output is completely over. But is this always the case? Who makes sure the different threads are run one after the other? Can I rely on this supposed order?
回答1:
A Future is an object holding a value which may become available at some point. This value is usually the result of some other computation:
- If the computation has not yet completed, we say that the Future is not completed.
- If the computation has completed with a value or with an exception, we say that the Future is completed.
Completion can take one of two forms:
When a Future is completed with a value, we say that the future was successfully completed with that value.
When a Future is completed with an exception thrown by the computation, we say that the Future was failed with that exception.
The simplest way to create a future object is to invoke the future method which starts an asynchronous computation and returns a future holding the result of that computation. The result becomes available once the future completes.
Note that Future[T] is a type which denotes future objects, whereas future is a method which creates and schedules an asynchronous computation, and then returns a future object which will be completed with the result of that computation.
doc
You can see more implementation details at github
来源:https://stackoverflow.com/questions/31597998/scala-processlogger-future-how-can-i-make-sure-all-line-callbacks-are-called