【发布时间】:2021-01-11 20:24:47
【问题描述】:
我想让我的方法打印出 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
【问题讨论】:
-
每个线程都有自己的锁,因此它们可以并行运行。您的通知的处理很难遵循 - 您可能只是忽略了一条可能的路径。
-
如果你想要顺序执行,为什么要使用线程?
标签: java multithreading