Как указал cHao, RaceHorse
расширяет Thread
, но вы создаете новый Thread
на лошадь.Я бы решил эту проблему противоположным образом: вместо RaceHorse
внедрить Runnable
.
Во-вторых, будет работать решение, использующее метод synchronized
, но общим правилом всегда является поиск класса в java.util.concurrent
это решит проблему первым.Эту проблему можно решить, используя AtomicReference
, чтобы гарантировать, что только одна лошадь получает трофей.
Наконец, возможен уклон в пользу лошади # 1, если основной поток запускает потоки лошадей вфиксированный порядок (это зависит от ВМ и от накладных расходов на запуск нового потока в вашей ОС.) Подумайте об использовании сигнала (например, CountDownLatch
), которого все лошади ждут перед запуском.
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
public class Runner {
public static void main(String args[]) {
AtomicReference<RaceHorse> winner =
new AtomicReference<RaceHorse>();
CountDownLatch startingPistol = new CountDownLatch(1);
RaceHorse horse1 = new RaceHorse("Lol", startingPistol, winner);
RaceHorse horse2 = new RaceHorse("BOL", startingPistol, winner);
Thread thread1 = new Thread(horse1);
Thread thread2 = new Thread(horse2);
thread1.start();
thread2.start();
startingPistol.countDown();
}
}
class RaceHorse implements Runnable {
private final String name;
private final CountDownLatch startingPistol;
private final AtomicReference<RaceHorse> winner;
public RaceHorse(String name,
CountDownLatch startingPistol,
AtomicReference<RaceHorse> winner)
{
this.name = name;
this.startingPistol = startingPistol;
this.winner = winner;
}
public void run()
{
try {
startingPistol.await();
for(int i = 1 ; i <= 5000; i++)
{
System.out.println(i+" "+name);
}
boolean iWon = winner.compareAndSet(null, this);
System.out.printf("%s %s.%n", name, iWon? "won": "lost");
} catch (InterruptedException ex) {
System.out.printf("%s was assasinated before the race started.%n", name);
Thread.currentThread().interrupt();
}
}
}