我是java中并发线程的新手。我正在尝试编写一个简单的赛马模拟代码。
我想知道哪个线程先完成。
下面的代码抛出错误:不兼容的类型:线程无法转换为Gate
winner = (Gate)Thread.currentThread();
Gate.java
public class Gate implements Runnable{
public String horseName;
public final int GATE_DISTANCE = 20;
public final int FINISH_LINE_DISTANCE = 100;
public CyclicBarrier barrier;
public Gate(CyclicBarrier barrier,String horseName){
this.horseName = horseName;
this.barrier = barrier;
}
public void run(){
//Walk all horses to respective racing gates before starting race
for(int distanceCovered = 0; distanceCovered < GATE_DISTANCE;){
distanceCovered += gallop();
int distanceLeft = GATE_DISTANCE - distanceCovered;
if(distanceLeft < 0){
distanceLeft = 0;
}
System.out.println(horseName + "\t\tgate distance left " + distanceLeft);
if(distanceLeft == 0){
break;
}
}
//Wait for all horses to be at racing gates
try{
barrier.await();
}
catch(InterruptedException ie){
System.out.println("INTERRUPTED");
}
catch(BrokenBarrierException bbe){
System.out.println("BROKEN");
}
//ACTUAL HORSE RACE
for(int distanceCovered = 0; distanceCovered < FINISH_LINE_DISTANCE;){
distanceCovered += gallop();
int distanceLeft = FINISH_LINE_DISTANCE - distanceCovered;
if(distanceLeft < 0){
distanceLeft = 0;
}
System.out.println(horseName + "\t\tgate distance left " + distanceLeft);
if(distanceLeft == 0){
break;
}
}
Main.done();
}
public int gallop(){
final int MIN_GALLOP = 1,
MAX_GALLOP = 10;
Random random = new Random();
int gallopRange = MAX_GALLOP - MIN_GALLOP + 1;
int totalGallop = random.nextInt(gallopRange) + MIN_GALLOP;
return totalGallop;
}
}
GateMain.java
public class GateMain{
private static Gate winner = null;
public static void main(String[] args) {
int horseCount = 5;
List<String> horseNames = new ArrayList<String>();
List<Thread> RG = new ArrayList<Thread>();
horseNames.add("Red Bullet");
horseNames.add("Green Furious");
horseNames.add("Pink Mirage");
horseNames.add("Blue Dash");
horseNames.add("Yellow Burst");
Scanner scan = new Scanner(System.in);
final CyclicBarrier cb = new CyclicBarrier(horseCount,new Runnable(){
public void run(){
System.out.print("\nALL HORSES ARE IN THEIR RESPECTIVE RACING GATES");
System.out.println("\nRACE BEGIN!!!\n");
}
});
for(int horseCtr = 0; horseCtr < horseCount; horseCtr++){
Gate rg = new Gate(cb,horseNames.get(horseCtr));
Thread thread = new Thread(rg);
thread.start();
RG.add(thread);
}
for(Thread thread: RG){
try{
thread.join();
}
catch(InterruptedException ie){
System.out.println("Thread Interrupted");
}
}
System.out.println(winner.horseName + "\t\t\twins!");
}
synchronized static void done(){
if(winner == null){
winner = (Gate)Thread.currentThread();
}
}
}
答案 0 :(得分:2)
我会使用全局AtomicInteger
。
public static AtomicInteger finishLine = new AtomicInteger(0);
每匹马(线程)都应该有自己的place
变量
int place;
当一匹马完成比赛时,它确定了自己的位置:
place = finishLine.incrementAndGet();
到达终点线的第一匹马将获得place=1
,第二匹马,place=2
,依此类推。然后,main()
例程必须检查每匹马,找出哪一匹place=1
。那将是胜利者。
这是一个不同的想法,受到越野足球赛终点线的启发:使用线程安全队列而不是AtomicInteger。
public static ArrayBlockingQueue<Horse> chute =
new ArrayBlockingQueue<>(NUMBER_OF_HORSES);
当每匹马到达终点线时,它会进入滑槽。
chute.add(this);
这样,就没有必要明确等待比赛结束,也没有必要明确地对终结者进行排序:
Horse win = chute.take(); //waits for the first horse to finish
Horse place = chute.take(); //waits for the second horse
Horse show = chute.take(); //...
答案 1 :(得分:1)
然而,根据Java的规则,只是在这里进行同步是行不通的。您还必须同步您希望线程读取的更新。取决于变量是什么,可能是也可能不是问题。
您可能需要更多地考虑您的线程模型,并在此描述您想要做什么。如果您不了解互斥,则可能还没有准备好设计线程代码。
如果您尝试从静态成员访问实例字段,我不得不想知道如何编译代码。
Thread.currentThread()返回您(或其他库代码)创建的实际Thread对象。这可以是一个Gate线程,但这一切都取决于它运行的Thread对象。最安全的是首先使用instanceof进行检查。
答案 2 :(得分:0)