如何创建线程来控制另一个线程?



我尝试制作简单的多线程机器人。他把头当线和两条腿,一条腿——一根线。一切正常,但是如何创建控制线程,控制每条腿?

我的代码是:

public class Controller implements CommandInterface{
private final Object monitor = new Object();
private int numOfSteps = 10;
class Legs implements Runnable {
private final String whichLeg;
Legs(String whichLeg) {
this.whichLeg = whichLeg;
}
@Override
public void run() {
for(int i = 0; i < numOfSteps;i++) {
synchronized (monitor) {
step();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
monitor.notify();
try {
monitor.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void step() {
System.out.println(whichLeg);
}
}
Legs left = new Legs("left feet");
Legs right = new Legs("right feet");
@Override
public void execute() {
new Thread(left).start();
new Thread(right).start();
}
}

要启动机器人,我使用此类:

public class ClientInterface {
public static void main(String [] args) {
new Controller().execute();
}
}

我知道我应该使用join()来等待另一个线程。 我想看到这样的结果:

Init head head sends make 1 step left feet head sends make 2 step right feet and so on...

我尝试在 Main 方法创建头线程并调用join()但它正在等待当前线程,但我需要等待腿.我试图像Thread head = new Thread(new Runnable{ tried here to run execute method });一样创建头线程,但这一切都不起作用。

有很多可能的选择。这是其中之一:
每条腿本身都成为监视器。当 Head 线程启动时,它开始通知/等待腿。因此,在第一次迭代中,头部将通知/等待第一条腿,在第二次迭代中,它将通知/等待第二条腿,依此类推直到最后。腿只是永远循环等待头部线程的通知。他们的工作是接收通知,打印适当的消息并向负责人发送通知。
这是草图:

interface CommandInterface {
void execute();
}
class Controller implements CommandInterface {
private static final int NUM_OF_STEPS = 10;
private final Legs[] legs = {
new Legs("left feet"),
new Legs("right feet")
};
@Override
public void execute() {
Executors.newSingleThreadExecutor().execute(() -> {
System.out.println("Init head");
for (Legs leg : legs) {
leg.start();
}
for (int i = 0; i < NUM_OF_STEPS; i++) {
try {
TimeUnit.SECONDS.sleep(1);
int currentLegIndex = i % legs.length;
synchronized (legs[currentLegIndex]) {
System.out.println("head sends make " + (i + 1) + " step");
legs[currentLegIndex].notify();
legs[currentLegIndex].wait();
}
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted!", e);
}
}
});
}
class Legs extends Thread {
private final String whichLeg;
Legs(String whichLeg) {
this.whichLeg = whichLeg;
}
@Override
public void run() {
while (true) {
try {
synchronized (this) {
this.wait();
step();
this.notify();
}
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted!", e);
}
}
}
private void step() {
System.out.println(whichLeg);
}
}
}
class ClientInterface {
public static void main(String [] args) {
new Controller().execute();
}
}

您也可以考虑创建共享CountDownLatch。我非常推荐阅读它的javadoc。我想你会理解这个想法,并自己创建一个更优雅的解决方案;)