【发布时间】:2015-12-29 17:01:38
【问题描述】:
我目前正在努力理解 Java 的多线程概念。我浏览了一个使用 Tortoise 和 Hare 示例来解释多线程概念的教程,并且在很大程度上理解了视频教程的语法和逻辑。在视频教程的最后,Youtuber 给出了一项涉及将多线程应用到奥林匹克赛道的作业。
利用我从示例中获得的知识,我能够创建 10 个线程(代表运动员)在一个循环中运行,执行 100 次(代表 100 米)。
我的挑战是,当线程调度程序让一名运动员在其他 9 名运动员之前跑到 100 米时,剩余的 9 个线程总是无法完成他们的比赛。在标准赛道中通常不会出现这种情况。事实上,名为 Usain Bolts 的 Thread 首先达到 100,这并不意味着 Yohan Blake 如果当时处于 90m 就应该停止奔跑。
我也有兴趣获取每个线程的距离(注意它们都使用相同的变量),以便我可以使用函数返回每个线程在比赛结束时的位置。
我做了什么(没用):
1)我尝试使用 if else 构造(包含九个“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();
}
}
【问题讨论】:
-
数组列表不是线程安全的。我没有看到通常用于并发的同步关键字......我没有展示你如何处理除了 arraylist 之外的比赛,可能使用阻塞队列或安全的东西,或者使用同步的关键工作
-
如果你想编写灵活健壮的多线程代码,你绝对应该避免直接寻址 Thread 类。使用 Runnable 定义您的任务,并通过 ExecutorService 使它们执行。然后,您将能够控制执行流程和停止条件。网上有很多 ExecutorService 用法的例子。
-
谢谢。但是有没有办法让这个程序直接使用 Thread 类来做我想做的事情?我想确定多线程中的基本概念。
-
恐怕您需要发布更多代码才能让我们找到问题所在。是的,可以通过直接使用
Thread类来做到这一点,但首先要注意ArrayList不是线程安全的警告,并将其包装在线程安全的集合包装器中。 -
List list = Collections.synchronizedList(new ArrayList());
标签: java multithreading netbeans