我怎样才能让一个线程做一些工作并让另一个线程加入并完成工作?

时间:2013-12-05 14:32:28

标签: java multithreading

我目前正在尝试学习线程的使用,我在线程上找到了一个练习,我正在尝试编写代码。

这是练习:

  
      
  1. 创建一个模拟400米跑步比赛的应用程序。

  2.   
  3. 创建五个线程组并给出名称(国家/地区名称)。

  4.   
  5. 然后应该是跑步者的数量(每组两个),并为每个跑步者线程命名。

  6.   
  7. 每个线程应该只运行距离的一半 - 200米,并且同一组中的下一个线程应该加入比赛以完成它。

  8.   
  9. 打印获胜者组名称(),所有线程都应完成比赛。

  10.   
  11. 打印每个小组完成比赛所需的时间,并突出显示获胜者的时间。

  12.   

所以,我的问题是第四点,每个线程应该运行一半的距离,我怎样才能完成我的初始线程并让下一个线程替换它并完成比赛?

到目前为止,这是我的代码:

public class RelayRacerDemo {

public static Thread runner[];

public static void main(String[] args) {
    RelayRacer rRacer = new RelayRacer();

    ThreadGroup country[] = new ThreadGroup[5];
    country[0] = new ThreadGroup("USA");
    country[1] = new ThreadGroup("Mexico");
    country[2] = new ThreadGroup("Italia");
    country[3] = new ThreadGroup("France");
    country[4] = new ThreadGroup("Brazil");

    runner = new Thread[10];
    runner[0] = new Thread(country[0] , rRacer, "USA racer 1");
    runner[1] = new Thread(country[0] , rRacer, "USA racer 2");
    runner[2] = new Thread(country[1] , rRacer, "Mexico racer 1");
    runner[3] = new Thread(country[1] , rRacer, "Mexico racer 2");
    runner[4] = new Thread(country[2] , rRacer, "Italia racer 1");
    runner[5] = new Thread(country[2] , rRacer, "Italia racer 2");
    runner[6] = new Thread(country[3] , rRacer, "France racer 1");
    runner[7] = new Thread(country[3] , rRacer, "France racer 2");
    runner[8] = new Thread(country[4] , rRacer, "Brazil racer 1");
    runner[9] = new Thread(country[4] , rRacer, "Brazil racer 2");

    runner[0].start();
    runner[2].start();
    runner[4].start();
    runner[6].start();
    runner[8].start();
}

}

和我的可运行代码:

public class RelayRacer implements Runnable{

public static Boolean winnerYet = false;

public void relayRace(){
    for(int distance=1; distance<=40; distance++){
        System.out.println("current runner " + Thread.currentThread().getName() 
                            + " has run " + distance + " meters");
        if(Thread.currentThread().getName().equals("USA racer 1") && distance == 20){
            threadJoin(distance, 1);
        }else if(Thread.currentThread().getName().equals("Mexico racer 1") && distance == 20){
            threadJoin(distance, 3);
        }else if(Thread.currentThread().getName().equals("Italia racer 1") && distance == 20){
            threadJoin(distance, 5);
        }else if(Thread.currentThread().getName().equals("France racer 1") && distance == 20){
            threadJoin(distance, 7);                
        }else if(Thread.currentThread().getName().equals("Brazil racer 1") && distance == 20){
            threadJoin(distance, 9);        
        }

        if(isGroupRacerWinner(distance)){
            System.out.println("Winning Country is " + Thread.currentThread().getThreadGroup().getName());
        }
    }
}


public void threadJoin(int distance, int nextRunner){

        RelayRacerDemo.runner[nextRunner].start();

        try 
        {RelayRacerDemo.runner[nextRunner].join();
        }catch (InterruptedException e) {e.printStackTrace();}

}

public Boolean isGroupRacerWinner(int distance){

    if(distance == 40 && winnerYet == false){
        winnerYet = true;
        return true;
    }else
        return false;
}

@Override
public void run(){
    this.relayRace();
}
}

我将其更改为40米,以便我可以更轻松地调试我的代码,

runner = thread;

这就是正在发生的事情:来自每个国家的第一个跑步者跑20米,然后第二个跑步者参加比赛,并且跑完整个比赛(全部40米,当它应该只运行一半的比赛从20-在第二名选手完成比赛后,第一名选手继续比赛并从20-40开始运行剩余的20米(当它应该在比赛的一半时停止。)

1 个答案:

答案 0 :(得分:1)

您的代码现在正在做什么:

  • 一名选手跑到20岁。
  • 然后他开始下一个线程,join()让他等到 新开始的线程结束。
  • 第二个线程现在执行for循环,但因为它是新的 例如,它也从1开始直到40。
  • 然后它完成并且第一个线程继续执行(其中 是在for循环的第20次迭代中。

所以最后你得到了20-40-20次跑步。

你需要确保第二名选手没有从第一名选手开始,第一名选手在第二名选手开始后完成比赛。

并检查一个团队是否赢得了isGroupRacerWinner(distance)你不需要每次迭代。如果在for循环后检查一次就足够了。因为团队只有完成for循环才有机会获胜。