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

问题描述

我想让我的方法打印出 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.

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

08-20 06:31
查看更多