System.out.println / System.err.println无效

时间:2018-03-19 13:09:37

标签: java multithreading concurrency java-8

我有以下代码:

  @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");
  }

结果文件只包含预期输出的一半:

  • 没什么。
  • DONE
  • FROM1:起始于:1521464569722
  • FROM2:起始于:1521464569722
  • FROM1:ID为11的主题
  • FROM2:ID为12的主题

你知道为什么文件不包含“Ending at”也没有例外吗?

1 个答案:

答案 0 :(得分:2)

如果您在写入后未关闭文件,则文件丢失某些内容是一种常见现象。许多finalizer()子类中有OutputStream个方法关闭了流,但它们并不总是有机会被调用,就像这里的情况一样。

主线程释放门并立即退出,其他线程快速运行,此时VM关闭,您无法确信事情已正确完成。

原始代码令人费解,很难修复"一些从头开始破碎的东西。例如,在实际代码中,您不会有2个线程竞争写入同一个文件。这没有用。

无论如何最好的"修复"因为这将是主线程等待其他线程完成(而不是休眠),然后关闭文件如下。

Thread t1 = new Thread(() -> ...
Thread t2 = new Thread(() -> ...
t1.start();
t2.start();

t1.join();
t2.join();
out.close();