【问题标题】:How to sych out and err streams in Java [duplicate]如何在Java中同步和错误流[重复]
【发布时间】:2013-11-08 02:30:22
【问题描述】:

在下面的代码中,如何按照我们期望的顺序制作黑色和红色的数字打印机,如下所示:

  • 1(黑色)
    1(红色)
    2(黑色)
    2(红色)

与其实际所做的相反(一些随机顺序取决于错误或输出流是否可用):

  • 1(黑色)
    2(黑色)
    1(红色)
    2(红色)

代码:

    package threads;

    public class CThread implements Runnable

{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 20; i++) {
        outt(i);
        err(i);
        }

    }

    synchronized public void outt(int i){
        System.out.println(i);
    }
    synchronized public void err(int i){
        System.err.println(i);
    }

    public static void main(String [] org){
        Thread th = new Thread(new CThread());
        th.start();
    }


}

【问题讨论】:

  • 您是在 IDE 还是在终端/控制台中运行它?
  • IDE 中的@DerFlatulator
  • 啊,我本来打算建议使用ANSI escape codes
  • 对未来回答者的评论:这不是可以通过刷新来解决的缓冲问题。
  • 另一个问题也没有回答这个问题。接受的解决方案不正确。

标签: java


【解决方案1】:

即使您尝试同步您的 Streams 的写入(System.outSystem.err 在这种情况下),它也不会阻止正在观看这些 Streams 的程序(在您的情况下是 Eclipse)正在读取这些流那个顺序。

在这之间有很多基础设施(包括可以按任何顺序对这些 IO 操作进行排序的操作系统)。

对于现实世界的应用程序,这类问题的答案是使用日志框架。使用这些,您可以将所有级别的所有消息写入同一个文件(通常在单独的线程中,按照它们记录的顺序)。

如果您不想使用日志记录框架并希望依赖 System.out / System.err,那么您无法可靠地控制此输出如何被 3rd 方应用程序读取。您唯一能做的就是通过使用公共锁对象同步(和刷新)IO 操作来同步这些流的写入。 但是请注意,这种技术对于任何多线程代码来说都是一个严重的瓶颈。

【讨论】:

    【解决方案2】:

    为输出和错误创建一个 ArrayList。而不是 System.out 和 System.err 附加到该列表。然后决定何时打印它并首先打印一个空的输出列表,然后打印并清空错误列表。必须同步。另外:打印点火后出现的新输出和错误将不会被排序 - 当然 - 这无法解决,因为 System.out 和 System.err 的输出在控制台中合并,先到先得。如果你想解决这个问题,你必须等到程序完成,然后打印所有输出和所有错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-20
      相关资源
      最近更新 更多