我试着运行了几个线程,如下图所示。
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
所以,线程的输出顺序可能是不同的, 但它并没有混在一起。它看起来是错误的。这种行为的原因是什么,如何解决这个问题(以随机顺序获取行)?
System.out
是基于缓冲区的,它不会在每条消息上冲刷流。
要想把它搞乱,可以尝试手动刷新。
Thread threadWinter = new Thread(() -> IntStream.range(1, 4)
.forEach((n) -> {
System.out.println("Winter");
System.out.flush();
}));
根据我的观察,我想说的是,在每个线程中只打印4个项目,不足以让线程打印足够长的时间来启动其他线程。试着在每个线程中打印像一百行。
你可能应该增加多个线程打印每个消息。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