我目前正在学习Java中Threads的基础知识,我正在尝试编写一个程序来模拟2个团队的2x200 Relay比赛。我想拥有2个团队(每个团队由一个ThreadGroup代表),每个团队有2个成员,每个成员必须运行200米。这里运行只是通过在for循环和打印中循环来模拟。我无法找到在线程组中以串行方式运行线程的直接方式
这是工人的样子
public class RelayRunner implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 200; i++) {
String name = Thread.currentThread().getName();
if (i % 50 == 0) {
System.out.format("%s ran %d m \n", name, i);
}
}
}
}
以下是主程序的外观
public class RelayRunnerMatch {
public static void main(String[] args) {
RelayRunner relayRunner = new RelayRunner();
ThreadGroup usa = new ThreadGroup("USA");
ThreadGroup germany = new ThreadGroup("GERMANY");
Thread usa1 = new Thread(usa, relayRunner, "usa1");
Thread germany1 = new Thread(germany, relayRunner, "germany1");
Thread usa2 = new Thread(usa, relayRunner, "usa2");
Thread germany2 = new Thread(germany, relayRunner, "germany2");
usa1.start();
germany1.start();
/* Now I would like to start the second thread in a group only if the first
thread in the same group has finished like in a real relay race. How??
*/
//usa1.join(); germany1.join();
//usa2.start(); germany2.start() --> Not good, usa2 must start immediately when usa1 has finished
}
}
我无法看到join()在这里有什么帮助,因为它会在第二组跑步者开始跑步之前等待两个线程完成。另外我意识到activeCount()只是一个估计,所以我也不确定是否使用它。 有没有一种解决方案可以在新的Concurrent API中使用服务(因为我还没有达到这一点)?
答案 0 :(得分:1)
您可以在相应的接力棒上创建两个接力棒对象和synchronize
,这样第二个线程就必须等到第一个接力棒释放接力棒 - 或者使用java.util.concurrent.locks
中的一些锁定 - 来实现相同。但是你的接力成员将参加谁先获得接力棒或接下来的接力棒,你无法定义一些真正的订单。
但正如Jarrod所说:当你有几个必须按顺序执行的任务时,你最好在同一个线程上执行它们:拥有一些runner-object并将它们添加到相应的relay-thread上的队列中,该队列调用它们的run-方法一个接一个。
答案 1 :(得分:1)
public class Player1 implements Runnable{
private final CountDownLatch countDownLatch;
private final String s;
public Player1(CountDownLatch c, String s){
this.countDownLatch=c;
this.s=s;
}
@Override
public void run() {
for(int i=0;i<200;i++){
System.out.println(s+":"+i);
}
countDownLatch.countDown();
}
}
public class Player2 implements Runnable{
private final CountDownLatch countDownLatch;
private final String s;
public Player2(CountDownLatch c, String s){
this.countDownLatch = c;
this.s=s;
}
@Override
public void run() {
try {
countDownLatch.await();
} catch (InterruptedException ex) {
Logger.getLogger(Player2.class.getName()).log(Level.SEVERE, null, ex);
}
for(int i=0;i<200;i++){
System.out.println(s+":"+i);
}
}
}
驱动程序:
public static void main(String[] args){
Thread[] grp1 = new Thread[2];
Thread[] grp2 = new Thread[2];
CountDownLatch c1 = new CountDownLatch(1);
CountDownLatch c2 = new CountDownLatch(1);
grp1[0]=new Thread(new Player1(c1, "grp1:player1"));
grp1[1]=new Thread(new Player2(c2, "grp1:player2"));
grp2[0]=new Thread(new Player1(c2, "grp2:player1"));
grp2[1]=new Thread(new Player2(c2, "grp2:player2"));
grp1[0].start();
grp2[0].start();
grp1[1].start();
grp2[1].start();
}