我有以下代码:
@Test
public void testMultipleUpdatesSameTime() {
final CyclicBarrier gate = new CyclicBarrier(3);
PrintStream out = null;
try {
out = new PrintStream(new FileOutputStream(
"C:\\pathToFile\\test2_output.txt"));
} catch (FileNotFoundException e1) {
System.err.println(e1);
}
System.setErr(out);
new Thread(() -> {
try {
gate.await();
} catch (InterruptedException e) {
System.err.println(e);
} catch (BrokenBarrierException e) {
System.err.println(e);
}
System.err.println("FROM1: Starting at: " + System.currentTimeMillis());
System.err.println("FROM1: Thread with ID: " + Thread.currentThread().getId());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.err.println(e);
}
System.err.println("FROM1: Ending at: " + System.currentTimeMillis());
}).start();
new Thread(() -> {
try {
gate.await();
} catch (InterruptedException e) {
System.err.println(e);
} catch (BrokenBarrierException e) {
System.err.println(e);
}
System.err.println("FROM2: Starting at: " + System.currentTimeMillis());
System.err.println("FROM2: Thread with ID: " + Thread.currentThread().getId());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.err.println(e);
}
System.err.println("FROM2: Ending at: " + System.currentTimeMillis());
}).start();
System.err.println("NOTHING YET");
try {
Thread.sleep(10000);
gate.await();
} catch (InterruptedException e) {
System.err.println(e);
} catch (BrokenBarrierException e) {
System.err.println(e);
}
System.err.println("DONE");
}
结果文件只包含预期输出的一半:
你知道为什么文件不包含“Ending at”也没有例外吗?
答案 0 :(得分:2)
如果您在写入后未关闭文件,则文件丢失某些内容是一种常见现象。许多finalizer()
子类中有OutputStream
个方法关闭了流,但它们并不总是有机会被调用,就像这里的情况一样。
主线程释放门并立即退出,其他线程快速运行,此时VM关闭,您无法确信事情已正确完成。
原始代码令人费解,很难修复"一些从头开始破碎的东西。例如,在实际代码中,您不会有2个线程竞争写入同一个文件。这没有用。
无论如何最好的"修复"因为这将是主线程等待其他线程完成(而不是休眠),然后关闭文件如下。
Thread t1 = new Thread(() -> ...
Thread t2 = new Thread(() -> ...
t1.start();
t2.start();
t1.join();
t2.join();
out.close();