Java线程被打断

问题描述 投票:1回答:1

我试着运行了几个线程,如下图所示。

Thread threadWinter = new Thread(() -> IntStream.range(1, 4).forEach((n) -> System.out.println("Winter")));
Thread threadSpring = new Thread(() -> IntStream.range(1, 4).forEach((n) -> System.out.println("Spring")));
Thread threadSummer = new Thread(() -> IntStream.range(1, 4).forEach((n) -> System.out.println("Summer")));
Thread threadAutumn = new Thread(() -> IntStream.range(1, 4).forEach((n) -> System.out.println("Autumn")));
threadWinter.start();
threadSpring.start();
threadSummer.start();
threadAutumn.start();

而每次运行的输出结果都是如下所示

Spring
Spring
Spring
Summer
Summer
Summer
Winter
Winter
Winter
Autumn
Autumn
Autumn

所以,线程的输出顺序可能是不同的, 但它并没有混在一起。它看起来是错误的。这种行为的原因是什么,如何解决这个问题(以随机顺序获取行)?

java multithreading java-threads
1个回答
3
投票

System.out 是基于缓冲区的,它不会在每条消息上冲刷流。

要想把它搞乱,可以尝试手动刷新。

Thread threadWinter = new Thread(() -> IntStream.range(1, 4)
    .forEach((n) -> {
        System.out.println("Winter"); 
        System.out.flush();
    }));

1
投票

根据我的观察,我想说的是,在每个线程中只打印4个项目,不足以让线程打印足够长的时间来启动其他线程。试着在每个线程中打印像一百行。


1
投票

你可能应该增加多个线程打印每个消息。System.out 是缓冲和全局的,还需要注意的是 println() 包括 隐性 flush(). 我会先用一个简单的类来打印信息。类似于:

static class MessagePrinter implements Runnable {
    private String msg;

    public MessagePrinter(String msg) {
        this.msg = msg;
    }

    public void run() {
        System.out.println(msg);
    }
}

然后你可以用一个圈来构建每个季节的四根线,把它们加到一个 List 然后用平行的无序流来实现。start() 的(16)条线。类似于:

public static void main(String[] args) {
    Runnable[] seasons = { new MessagePrinter("Winter"),
            new MessagePrinter("Spring"), 
            new MessagePrinter("Summer"),
            new MessagePrinter("Autumn")
    };
    List<Thread> al = new ArrayList<>();

    for (Runnable r : seasons) {
        for (int i = 0; i < 4; i++) {
            al.add(new Thread(r));
        }
    }
    al.stream().unordered().parallel().forEach(Thread::start);
    for (Thread t : al) {
        try {
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

这在我的系统上一直产生不可预测的结果排序。样品运行。

Summer
Summer
Winter
Summer
Summer
Autumn
Autumn
Winter
Winter
Spring
Winter
Spring
Spring
Spring
Autumn
Autumn

如果想获得更极端的 "乱七八糟 "的输出,可修改 MessagePrinter.run() 办法 flush()yield() 每一个字符后。像。

public void run() {
    for (int i = 0; i < msg.length(); i++) {
        System.out.print(msg.charAt(i));
        System.out.flush();
        Thread.yield();
    }
    System.out.println();
}

样品输出

SSuummerm
mer
Summer
Spring
Spring
SumWinmter
er
WiAutunmAutumn
tSprin
Ser
pringAutumng
n

AWinWitntuer
teumn
r
© www.soinside.com 2019 - 2024. All rights reserved.