java - 如何“同步”线程依次运行?
问题描述
我想让我的方法打印出 4 行“Hello world!”,但我的代码似乎无法按我的意愿工作。有没有办法保证它会按照我的意愿运行?有时我得到 2 行,有时单词顺序错误,等等。有时它会按我想要的方式打印单词,但大多数情况下不会。对于我的代码中可能伤害您的眼睛的任何错误,我深表歉意,我仍在学习,因此我在这里。感谢您的任何建议。
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
解决方案
线程应该是Asynchronous,这是您在执行中看到的行为。
如果您需要强制它们同步,请查看https://www.baeldung.com/java-executor-service-tutorial中的 Future 。您可以创建一个 List 并使用 executor 和.get方法迭代该列表以等待每个线程的结果。
我不确定您的用例,但线程是一个非常具有挑战性的主题。
推荐阅读
- java - 如何在 SpringBoot application.properties 文件中软编码映射而不是硬编码?
- javascript - 如何从 unicode 字符串中获取正确的元素?
- netcdf - 如何连接具有不同尺寸大小的多个 netCDF 文件?
- r - 如何运行分位数回归,在每个循环中添加额外四分之一的数据
- javascript - 单击时无法创建“a”元素,随后 classList.toggle() 不起作用
- python - 如何在遵守 PEP8 的同时编写长的 os.path.join 链
- python - 与 pytest 并行运行单元测试?
- c# - 更新和删除冗余节点树
- typescript - 如何在 Typescript 中表达函数契约?
- javascript - 为什么我作为图像包含的视图之间存在差异?