一般认为Stream(包括InputStream和OutputStream)不是线程安全的(如 这篇 ),但下面的程序运行多次后未观察到OutputStream.write()方法的原子性被破坏的现象:每个线程向文件输出长度为1000的字符组(从A到),20个线程并发没有出现字符组交错输出。
StreamQueueTest.java package streamVsQueue; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.OutputStream; public class StreamQueueTest { public static void main(String[] args) { OutputStream out = null; try { out = new FileOutputStream("concurrentout.txt", false); } catch (FileNotFoundException e) { e.printStackTrace(); } for (int i = 0; i < 20; i++) { IntCounter cc = new IntCounter(i, out); new Thread(cc).start(); } } }
IntCounter.java
package streamVsQueue; import java.io.IOException; import java.io.OutputStream; public class IntCounter implements Runnable { private final int cnt; OutputStream out; public IntCounter(int i, OutputStream oup) { cnt = i; out = oup; } @Override public void run() { int bytelen = 1000; byte[] buf = new byte[bytelen]; for (int i = 0; i < bytelen; i++) { buf[i] = (byte) (65 + cnt); } try { out.write(buf); } catch (IOException e) { e.printStackTrace(); } } }
至于BlockingQueue,文档明确说明是线程安全的,各个读取操作都有内部锁,所以就不测试了,安全起见,新版本的GODU就用这个数据结构吧。