如何“同步"线程一个接一个地运行? [英] How to "synchronize" threads to run one after another in order?

查看:52
本文介绍了如何“同步"线程一个接一个地运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想让我的方法打印出 4 行Hello world!",但我的代码似乎无法正常工作.有没有办法保证它会按我的意愿运行?有时我得到 2 行,有时单词顺序错误,等等.有时它会按照我想要的方式打印单词,但大多数情况下不会.很抱歉我的代码中的任何错误可能会伤害您的眼睛,我仍在学习,因此我在这里.感谢您的建议.

I want to make my method to print out 4 lines of "Hello world!", but my code seems to not work as I want. Is there a way that I have a guarantee that it will run as I want? Sometimes I get 2 lines, sometimes the words are in wrong order, and so on. Sometimes it prints words how I want, but mostly not. Sorry for any mistakes in my code that can hurt your eyes, I'm still learning and im here because of it. Thanks for any advice.

public class PrintHelloWorld {

final Lock lock = new ReentrantLock(true);
private volatile String state = "inactive";

public void printHelloWorld() {
    LocksManager manager = new LocksManager();

    Thread t1 = new Thread(() -> {
        synchronized (manager.getObject(0)) {
            for (int i = 0; i < 4; i++) {
                System.out.print("Hello ");
                try {
                    manager.notify(1);
                    state = "running t2";
                    while(!state.equals("running t1"))
                        manager.wait(0);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    });

    Thread t2 = new Thread(() -> {
        synchronized (manager.getObject(1)) {
            for (int i = 0; i < 4; i++) {
                System.out.print("world");
                try {
                    manager.notify(2);
                    state = "running t3";
                    while (!state.equals("running t2"))
                        manager.wait(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    });

    Thread t3 = new Thread(() -> {
        synchronized (manager.getObject(2)) {
            for (int i = 0; i < 4; i++) {
                System.out.println("!");
                try {
                    manager.notify(0);
                    state = "running t1";
                    while (!state.equals("running t3"))
                        manager.wait(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    });
    {
        t1.start();
        t2.start();
        t3.start();
        try {
            t1.join();
            t2.join();
            t3.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

private class LocksManager {
    private volatile Object[] locks;

    public LocksManager() {
        locks = new Object[3];

        for (int i=0; i<3; i++)
            locks[i] = new Object();
    }

    public Object getObject(int number) {
        return locks[number];
    }

    public void wait(int number) throws InterruptedException {
        synchronized (locks[number]) {
            locks[number].wait();
        }
    }

    public void notify(int number) {
        synchronized (locks[number]) {
            locks[number].notify();
        }
    }

}
}

输出应该是这样的:

Hello world!
Hello world!
Hello world!
Hello world!

但有时看起来像这样:

Hello world!
Hello !
worldHello !
worldHello !
world

或者这个:

Hello !
world

推荐答案

线程应该是异步,这是您在执行中看到的行为.

Threads are supposed to be Asynchronous, which is the behavior you see in your executions.

如果您需要强制它们同步,请查看 中的 Future'shttps://www.baeldung.com/java-executor-service-tutorial.您可以创建一个列表并使用执行器和 .get 方法迭代列表以等待每个线程的结果.

If you need to force them to be synchronous, please take a look at Future's in https://www.baeldung.com/java-executor-service-tutorial. You can make a List and iterate the list using an executor and the .get method to wait for a result of each thread.

我不确定您的用例,但线程是一个非常具有挑战性的主题.

I'm not sure about you use case, but threads is a very challenging subject.

这篇关于如何“同步"线程一个接一个地运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆