While playing around with concurrent calls to println
in Clojure I found that its behaviour is different from Java's System.out.println
.
What in Java I would write
class Pcalls {
public static void main(String[] args) {
Runnable[] fns = new Runnable[3];
for (int i = 0; i < 3; i++) {
fns[i] = new Runnable() {
@Override public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("Hello iteration " + i);
}
}
};
}
for (Runnable fn : fns) new Thread(fn).start();
}
}
I paraphrased in Clojure as:
(doall (apply pcalls
(repeat 3 #(dotimes [i 5] (println "Hello iteration" (inc i))))))
Unfortunately, in the Clojure version the output lines often appear interleaved:
Hello iterationHello iteration 1
Hello iteration Hello iteration 2
Hello iteration 3
1
Hello iteration 4
1
Hello iteration Hello iteration5
Hello iteration 2
Hello iteration 23
Hello iteration Hello iteration 4
3Hello iteration
5
Hello iteration 4
Hello iteration 5
(nil nil nil)
In Java this never happens, every message is printed on its own line.
Can you explain how and why Clojure's println
differs from Java's, and how to arrive at a similar kind of "thread-safe" behaviour with println
in Clojure?