0

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

  • 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();
    }


}
4

2 回答 2

2

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

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

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

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

于 2013-11-08T07:20:40.437 回答
0

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

于 2013-11-08T07:10:04.670 回答