我目前正致力于理解多线程的Java概念 . 我经历了一个使用Tortoise和Hare示例的教程来解释多线程的概念,并且在很大程度上我理解了视频教程的语法和逻辑 . 在视频教程的最后,Youtuber做了一项任务,涉及将多线程应用于奥运赛道 .
使用我的示例中的知识,我能够创建在循环内运行的10个线程(代表运动员),执行100次(代表100米) .
我的挑战是,当线程调度员使运动员在其他9名运动员之前达到100米时,其余9个线程总是不能完成他们的比赛 . 在标准赛道中通常不是这种情况 . 一个名为Usain Bolts的线程首先达到100,这并不意味着如果Yohan Blake当时处于90米,他应该停止运行 .
我也有兴趣获得每个线程的距离(注意它们都使用相同的变量),这样我就可以使用函数在比赛结束时返回每个线程的位置 .
我做了什么(没有用):1)我试图使用if else结构(包含9个"else"语句)来将每个执行线程的距离分配给新的整数变量 . (使用Thread.currentThread() . getName()属性和每个线程的名称)但这对我来说效果不佳 . 这是尝试使用他们的距离单独为运动员提供位置,但对未完成比赛的9名运动员没有任何作用 .
2)我还尝试使用ArrayList在运行时填充距离,但由于一些奇怪的原因,每次想要添加另一个距离时,它仍会覆盖距离 .
以下是我的代码:
package olympics100meters;
import java.util.ArrayList;
public class HundredMetersTrackRules implements Runnable {
public static String winner;
public void race() {
for (int distance=1;distance<=50;distance++) {
System.out.println("Distance covered by "+Thread.currentThread ().getName ()+" is "+distance+" meters.");
boolean isRaceWon=this.isRaceWon(distance);
if (isRaceWon) {
ArrayList<Integer> numbers = new ArrayList();
numbers.add(distance);
System.out.println("testing..."+numbers);
break;
}
}
}
private boolean isRaceWon(int totalDistanceCovered) {
boolean isRaceWon=false;
if ((HundredMetersTrackRules.winner==null)&& (totalDistanceCovered==50)) {
String winnerName=Thread.currentThread().getName();
HundredMetersTrackRules.winner=winnerName;
System.out.println("The winner is "+HundredMetersTrackRules.winner);
isRaceWon=true;
}
else if (HundredMetersTrackRules.winner==null) {
isRaceWon=false;
}
else if (HundredMetersTrackRules.winner!=null) {
isRaceWon=true;
}
return isRaceWon;
}
public void run() {
this.race();
}
}
这是我的主要方法(我把它减少到5名运动员,直到我解决问题):
public class Olympics100Meters {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
HundredMetersTrackRules racer=new HundredMetersTrackRules();
Thread UsainBoltThread=new Thread(racer,"UsainBolt");
Thread TysonGayThread=new Thread (racer,"TysonGay");
Thread AsafaPowellThread=new Thread(racer,"AsafaPowell");
Thread YohanBlakeThread=new Thread (racer,"YohanBlake");
Thread JustinGatlinThread=new Thread (racer,"JustinGatlin");
UsainBoltThread.start();
TysonGayThread.start();
AsafaPowellThread.start();
YohanBlakeThread.start();
JustinGatlinThread.start();
}
}
2 回答
这是由
isRaceWon()
方法实现引起的 . 您可以在每个跑步者的每个仪表上检查它 . 一旦第一个跑步者达到100米,就会在每个跑步者循环的下一步调用break
(每个循环赢得比赛顺便说一句,使用
volatile statuc String
获胜者's name, to avoid java'的内存模型模糊是有意义的 .如果最终目标是获取位置,则创建一个类字段
public List<String> finishingOrder = new ArrayList<String>
和一个方法finish
并在“运行”循环后调用它
不要忘记为
main
中的所有跑步者线程调用join()
. 之后,finishingOrder
将按顺序包含名称 .只要共享
winner
字段设置为非空(即某人获胜),下面的代码片段就会导致isRaceWon
为HundredMetersTrackRules
的每个实例返回true:这反过来导致
race()
中的循环中断Runnable
的每个实例 . 退出run()
方法,终止线程 .问题只是一个逻辑错误,并不是特定于线程 . 但是,正如其他海报所提到的那样,您可以在此代码中采用一些线程最佳实践,例如将
volatile
用于线程共享的字段 .