我有以下代码:

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


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


还没有
完成
FROM1:开始于:1521464569722
FROM2:开始于:1521464569722
FROM1:ID为11的线程
FROM2:ID为12的线程


您是否知道为什么文件不包含“结尾为”或异常?

最佳答案

如果您在写入后不关闭文件,则经常会丢失文件的某些内容。许多finalizer()子类中都有OutputStream方法会关闭流,但是在这种情况下,它们并不总是有被调用的机会。

主线程释放闸门并立即退出,其他线程迅速运行,此时虚拟机已关闭,您不能相信事情能正确完成。

原始代码令人费解,很难“修复”从头开始的问题。例如,在真实代码中,您不会有2个线程竞争写入同一文件中。那只是没有道理。

无论如何,最好的“解决方案”是让主线程等待其他线程完成(而不是休眠),然后按如下所示关闭文件。

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

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

关于java - System.out.println/System.err.println不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49363812/

10-11 00:08