Java线程被破坏了

Java线程被破坏了,java,multithreading,java-threads,Java,Multithreading,Java Threads,我尝试运行以下几个线程: 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 th

我尝试运行以下几个线程:

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
每个运行输出如下所示:

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();
    }));
out是基于缓冲区的,它不会刷新每条消息上的流

若要将其弄糟,请尝试手动冲洗

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

根据我的观察,我认为在每个线程中只打印4个项目不足以让线程打印足够长的时间,以使其他线程开始打印。试着在每个线程中打印100行。

根据我的观察,我认为在每个线程中只打印4个项目不足以让线程打印足够长的时间,以便其他线程开始打印。尝试在每个线程中打印100行。

您可能应该添加多个线程来打印每条消息。System.out是缓冲的,并且是全局的,值得注意的是println包含一个隐式刷新。我将从一个简单的类开始打印消息。大概

static class MessagePrinter implements Runnable {
    private String msg;

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

    public void run() {
        System.out.println(msg);
    }
}
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();
        }
    }
}
然后,您可以使用循环为每个季度构建四个线程,将它们添加到列表中,然后使用并行无序流启动16个线程。大概

static class MessagePrinter implements Runnable {
    private String msg;

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

    public void run() {
        System.out.println(msg);
    }
}
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();
        }
    }
}
要获得更混乱的输出,请修改MessagePrinter.run方法,使其在每个字符后刷新并生成。像

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

您可能应该添加多个线程来打印每条消息。System.out是缓冲的,并且是全局的,值得注意的是println包含一个隐式刷新。我将从一个简单的类开始打印消息。大概

static class MessagePrinter implements Runnable {
    private String msg;

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

    public void run() {
        System.out.println(msg);
    }
}
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();
        }
    }
}
然后,您可以使用循环为每个季度构建四个线程,将它们添加到列表中,然后使用并行无序流启动16个线程。大概

static class MessagePrinter implements Runnable {
    private String msg;

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

    public void run() {
        System.out.println(msg);
    }
}
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();
        }
    }
}
要获得更混乱的输出,请修改MessagePrinter.run方法,使其在每个字符后刷新并生成。像

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

System.out是一个缓冲打印流。你什么意思?修好它?@ElliottFrisch-谢谢!你是说,缓冲区一次指向所有行?我更喜欢用七弦琴随机打印,看起来不对。对你来说,也许吧,但这并没有错。当您在不同的非同步线程中执行不同的活动时,您实际上是在说,我不关心它们发生的顺序。如果您需要某些事情以特定的顺序发生,那么最好的方法是在同一个线程中完成所有这些事情。如何以随机顺序完成这些事情-执行顺序完全掌握在操作系统调度程序手中。如果它认为按顺序执行某件事情更快,因为它很小,那么它就会这样做。不要期望像这样的多线程代码有任何顺序,包括期望得到一些随机的东西。嗯……计算机真的很快。尝试100000000,每25000000.System.out打印一次,这是一个缓冲打印流。你什么意思?修好它?@ElliottFrisch-谢谢!你是说,缓冲区一次指向所有行?我更喜欢用七弦琴随机打印,看起来不对。对你来说,也许吧,但这并没有错。当您在不同的非同步线程中执行不同的活动时,您实际上是在说,我不关心它们发生的顺序。如果您需要某些事情以特定的顺序发生,那么最好的方法是在同一个线程中完成所有这些事情。如何以随机顺序完成这些事情-执行顺序完全掌握在操作系统调度程序手中。如果它认为按顺序执行某件事情更快,因为它很小,那么它就会这样做。不要期望像这样的多线程代码有任何顺序,包括期望得到一些随机的东西。嗯……计算机真的很快。尝试100000000,每25000000打印一次。谢谢-不幸的是,这没有帮助+我使用range1,100@Loom你给所有的线都加了齐平吗?在发布之前,我可能会把它搞砸,即使是在[1-3]范围内。请注意,这并不是一个可以期待的明确行为。因此,您可能希望多次运行该代码段:PrintStream System.out配置为自动刷新,正如注释所示,这意味着在写入字节数组、调用其中一个println方法或写入换行符或字节“\n”后自动调用刷新方法。@AndrewTobilko-10 000对我有用。同一季节,连续出现约500行代码谢谢-不幸的是,这没有帮助+我使用range1,100@Loom你给所有的线都加了齐平吗?在发布之前,我可能会把它搞砸,即使是在[1-3]范围内。请注意,这并不是一个可以期待的明确行为。因此,您可能需要多次运行代码段:PrintStream System.out配置为自动刷新,正如注释所示,这意味着刷新方法是自动的
在写入字节数组后调用CALL,调用一个println方法,或者写入换行符或字节'\n'。AndrewTobilko-10000为我工作。同样的季节里,也不断地有大约500行的片段,谢谢。不幸的是,这没用,谢谢你。不幸的是,它没有帮助实际上,我想为线程切换制作演示。因此,具有一个字符串输出的16个线程不能用于此目的。但是,您的第二封逐字发送的MessagePrinter::run工作正常。谢谢你+1实际上,我想为线程切换制作演示。因此,具有一个字符串输出的16个线程不能用于此目的。但是,您的第二封逐字发送的MessagePrinter::run工作正常。谢谢你+1