多线程中:如何确定哪个线程先停止

发布于 2024-09-12 07:26:10 字数 964 浏览 8 评论 0 原文

编写一个名为 RaceHorse 的类,它扩展了 Thread。每匹 RaceHorse 都有一个名称和 run() 方法,该方法会显示该名称 5000 次。编写一个 Java 应用程序来实例化 2 个 RaceHorse 对象。最后跑完的赛马就是失败者。

这就是问题所在。 我已经为两个运行线程的两个类编写了代码 以下是代码:

RaceHorse

class RaceHorse extends Thread
{
    public String name;
    public RaceHorse(String name)
    {
        this.name = name;
    }
    public void run()
    {
        for(int i = 1 ; i <= 5000; i++)
        {
            System.out.println(i+"  "+name);
        }
        System.out.println(name+" finished.");
    }
}

Runner

class Runner{
    public static void main(String args[])
    {
        RaceHorse obj = new RaceHorse("Lol");
        RaceHorse obj2 = new RaceHorse("BOL");
        Thread t = new Thread(obj);
        Thread t2 = new Thread(obj2);
        t.start();
        t2.start();
    }
}

现在我的问题是我无法找到哪个线程首先完成以及哪秒完成,即哪匹马获胜以及输了。!

Write a class named RaceHorse that extends Thread. Each RaceHorse has a name and run() method that displays the name 5000 times. Write a Java application that instantiates 2 RaceHorse objects. The last RaceHorse to finish is the loser.

This is the question.
I have written the code for the two classes two run the thread
Here are the codes:

RaceHorse

class RaceHorse extends Thread
{
    public String name;
    public RaceHorse(String name)
    {
        this.name = name;
    }
    public void run()
    {
        for(int i = 1 ; i <= 5000; i++)
        {
            System.out.println(i+"  "+name);
        }
        System.out.println(name+" finished.");
    }
}

Runner

class Runner{
    public static void main(String args[])
    {
        RaceHorse obj = new RaceHorse("Lol");
        RaceHorse obj2 = new RaceHorse("BOL");
        Thread t = new Thread(obj);
        Thread t2 = new Thread(obj2);
        t.start();
        t2.start();
    }
}

Now my problem is I am unable to find which of the thread finishes first and which seconds, i.e. which of the horse wins and which loses.!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

忆梦 2024-09-19 07:26:10

首先:您的 RaceHorse 对象本身就是线程。您应该能够说 obj.start(); 并且它也能正常工作。因此,完全删除 tt2

接下来,您需要某种方法来通知主线程有关获胜者的信息。

public void run()
{
    ... your loop stuff ...
    // this is how we're going to do the notification.
    Runner.done();
}

public class Runner
{
    private static RaceHorse winner = null;
    synchronized static void done()
    {
        // Threads calling this are going to be RaceHorse objects.
        // Now, if there isn't already a winner, this RaceHorse is the winner.
        if (winner == null) winner = (RaceHorse) Thread.currentThread();
    }

    public static void main(String[] args)
    {
         ... create the horses ...
         // start the horses running
         obj.start();
         obj2.start();

         // wait for them to finish
         obj.join();
         obj2.join();

         System.out.println(winner.name + " wins!");
    }
}

First off: your RaceHorse objects are themselves threads. You should be able to say obj.start(); and it'd work just as well. So remove t and t2 entirely.

Next, you'll need some way to notify the main thread about the winner.

public void run()
{
    ... your loop stuff ...
    // this is how we're going to do the notification.
    Runner.done();
}

public class Runner
{
    private static RaceHorse winner = null;
    synchronized static void done()
    {
        // Threads calling this are going to be RaceHorse objects.
        // Now, if there isn't already a winner, this RaceHorse is the winner.
        if (winner == null) winner = (RaceHorse) Thread.currentThread();
    }

    public static void main(String[] args)
    {
         ... create the horses ...
         // start the horses running
         obj.start();
         obj2.start();

         // wait for them to finish
         obj.join();
         obj2.join();

         System.out.println(winner.name + " wins!");
    }
}
浪推晚风 2024-09-19 07:26:10

毫无疑问有更好的方法,但一种方法可能是创建一个线程安全的类(例如“Trophy”),有一个仅在第一次调用时返回 true 的方法“getTrohpy”,并传递对实例的引用两个线程都获得奖杯。

There's no doubt a better way, but one method might be to create a class (e.g. 'Trophy') that is thread safe, has a method 'getTrohpy' that only returns true on the first call, and pass a reference to an instance of Trophy to both threads.

孤独难免 2024-09-19 07:26:10
public class StackOverflow {

    public static void main(String[] args) {
         RaceHorse obj = new RaceHorse("Lol"); 
            RaceHorse obj2 = new RaceHorse("BOL"); 
            Thread t = new Thread(obj); 
            Thread t2 = new Thread(obj2); 
            t.start(); 
            t2.start(); 

    }       
    }
class RaceHorse extends Thread 
{ 
    //public String name; 
    public RaceHorse(String name) 
    { 
        this.setName(name); 
    } 
    public void run() 
    { 
        for(int i = 1 ; i <= 5000; i++) 
        { 
            System.out.println(i+"  "+this.getName()); 
            try {
                Thread.sleep(250);
            } catch (InterruptedException e) {

                e.printStackTrace();
            }
        } 
        System.out.println(this.getName()+" finished."); 
    } 
} 
public class StackOverflow {

    public static void main(String[] args) {
         RaceHorse obj = new RaceHorse("Lol"); 
            RaceHorse obj2 = new RaceHorse("BOL"); 
            Thread t = new Thread(obj); 
            Thread t2 = new Thread(obj2); 
            t.start(); 
            t2.start(); 

    }       
    }
class RaceHorse extends Thread 
{ 
    //public String name; 
    public RaceHorse(String name) 
    { 
        this.setName(name); 
    } 
    public void run() 
    { 
        for(int i = 1 ; i <= 5000; i++) 
        { 
            System.out.println(i+"  "+this.getName()); 
            try {
                Thread.sleep(250);
            } catch (InterruptedException e) {

                e.printStackTrace();
            }
        } 
        System.out.println(this.getName()+" finished."); 
    } 
} 
述情 2024-09-19 07:26:10

正如 cHao 指出的,RaceHorse 扩展了 Thread,但您为每匹马创建了一个新的 Thread。我会以相反的方式解决这个问题,让 RaceHorse 实现 Runnable 来代替。

其次,使用同步方法的解决方案是可行的,但一般规则始终是在 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();
        }
    }

}

As cHao pointed out, RaceHorse extends Thread but you are creating a new Thread per horse. I would solve it the opposite way, by having RaceHorse implement Runnable instead.

Secondly, the solution using a synchronized method will work, but a general rule is always look for a class in java.util.concurrent that will solve the problem first. This one can be solved using an AtomicReference to ensure that only one horse takes the trophy.

Lastly, there could be a bias in favour of horse #1, if the main thread starts the horses' threads in a fixed order (this depends on the VM and on the overhead of starting a new thread on your OS.) Consider using a signal (for example a CountDownLatch) that all horses wait for before starting.

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();
        }
    }

}
过期以后 2024-09-19 07:26:10

我不会为你编写代码;但您应该查看 notify 方法(请参阅 此处)。

一种方法可能是:一旦线程完成,它将wait()等待其他线程通知(或notifyAll())。

另一种更优雅的解决方案是在共享对象上使用同步块; syncrhonized(obj) 语句将位于 run() 方法的末尾。在该语句中,您可以放入打印行或您认为有助于确定谁赢得比赛的任何其他代码。

I am not going to write the code for you; but you should take a look at the notify method (see here) to be used.

One approach could be: once a thread has finished it will wait() for the other thread(s) to notify (or notifyAll()).

Another, more elegant solution, would consist of using a synchronized block on a shared object; the syncrhonized(obj) statement would be at the end of the run() method. Into that statement you could put a printline or any other code you would deem useful to determine who won the race.

耶耶耶 2024-09-19 07:26:10

这将在 main 的末尾起作用:

boolean alive1 = true;
boolean alive2 = true;

while (alive1 && alive2) {
   alive1 =  obj.isAlive();
   alive2 =  obj2.isAlive();
   if (!alive1 && !alive2) {
       // Too close to call
   }
   if (!alive1) {
       // obj wins,
   }
   if (!alive2) {
       // obj2 wins,
   }
}

This will work at the end of the main :

boolean alive1 = true;
boolean alive2 = true;

while (alive1 && alive2) {
   alive1 =  obj.isAlive();
   alive2 =  obj2.isAlive();
   if (!alive1 && !alive2) {
       // Too close to call
   }
   if (!alive1) {
       // obj wins,
   }
   if (!alive2) {
       // obj2 wins,
   }
}
月下客 2024-09-19 07:26:10

我迟到了,但我在寻找如何处理多个正在运行的线程的第一个结果时发现了这一点。我认为最简单的方法是使用 ArrayBlockingQueue 它给你这样的东西。

public class RaceHorse extends Thread {
        private ArrayBlockingQueue<RaceHorse> finishedRaceHorses;

        public RaceHorse(String name) {
            super(name);
        }

        public void run() {
            for (int i = 1; i <= 50; i++) {
                System.out.println(i + "  " + getName());
            }
            System.out.println(getName() + " finished.");

            finishedRaceHorses.offer(this);
        }

        public void setFinishedRaceHorses(ArrayBlockingQueue<RaceHorse> finishedRaceHorses) {
            this.finishedRaceHorses = finishedRaceHorses;
        }
    }

    public class Race {
        private final List<RaceHorse> raceHorses;

        public Race(List<RaceHorse> raceHorses) {
            this.raceHorses = raceHorses;
        }

        public RaceHorse go() throws InterruptedException {
            ArrayBlockingQueue<RaceHorse> finishedRaceHorses = new ArrayBlockingQueue<RaceHorse>(raceHorses.size());
            for (RaceHorse raceHorse : raceHorses) {
                raceHorse.setFinishedRaceHorses(finishedRaceHorses);
                raceHorse.start();
            }

            return finishedRaceHorses.take();
        }
    }

public class Runner {
    public static void main(String args[])
    {
        RaceHorse horseOne = new RaceHorse("Lol");
        RaceHorse horseTwo = new RaceHorse("BOL");

        Race race = new Race(Arrays.asList(horseOne, horseTwo));
        try {
            RaceHorse winner = race.go();
            System.out.println("The winner is " + winner.getName());
        } catch (InterruptedException e) {
            System.out.println("The race was interrupted, maybe by a streaker?");
        }
    }
}

I'm late to the party, but I found this while looking for how to process the first result from a number of running threads. I think the easiest way is to use an ArrayBlockingQueue which gives you something like this.

public class RaceHorse extends Thread {
        private ArrayBlockingQueue<RaceHorse> finishedRaceHorses;

        public RaceHorse(String name) {
            super(name);
        }

        public void run() {
            for (int i = 1; i <= 50; i++) {
                System.out.println(i + "  " + getName());
            }
            System.out.println(getName() + " finished.");

            finishedRaceHorses.offer(this);
        }

        public void setFinishedRaceHorses(ArrayBlockingQueue<RaceHorse> finishedRaceHorses) {
            this.finishedRaceHorses = finishedRaceHorses;
        }
    }

    public class Race {
        private final List<RaceHorse> raceHorses;

        public Race(List<RaceHorse> raceHorses) {
            this.raceHorses = raceHorses;
        }

        public RaceHorse go() throws InterruptedException {
            ArrayBlockingQueue<RaceHorse> finishedRaceHorses = new ArrayBlockingQueue<RaceHorse>(raceHorses.size());
            for (RaceHorse raceHorse : raceHorses) {
                raceHorse.setFinishedRaceHorses(finishedRaceHorses);
                raceHorse.start();
            }

            return finishedRaceHorses.take();
        }
    }

public class Runner {
    public static void main(String args[])
    {
        RaceHorse horseOne = new RaceHorse("Lol");
        RaceHorse horseTwo = new RaceHorse("BOL");

        Race race = new Race(Arrays.asList(horseOne, horseTwo));
        try {
            RaceHorse winner = race.go();
            System.out.println("The winner is " + winner.getName());
        } catch (InterruptedException e) {
            System.out.println("The race was interrupted, maybe by a streaker?");
        }
    }
}
心清如水 2024-09-19 07:26:10
I have tried this problem and solved it using following code. There is room for improvement but for me this code worked perfectly :

1.RacingGame.java
/
package game;

import gamingObject.Horse;
import gamingObject.Race;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class RacingGame {

    /**
     * @param args
     */

    public static Map<Integer, List<String>> raceToWinners = new HashMap<Integer, List<String>>();
    public static int currentRace = 1;
    public static boolean trackComplete = false;
    private static boolean newTrackBegin;
    private static boolean flag = true;
    private static boolean race6Begin = false;
    private static boolean race7Begin = false;
    private static Object mutex = new Object();
    private int frstHorseInNextRace = 0;

    public static void main(String[] args) throws InterruptedException {
        ExecutorService exeService = Executors.newFixedThreadPool(5);
        /*
         * Logic to conduct first 5 races (total horses/total track) so here
         * total horses = 25 and tracks = 5 hence initial and compolsuary races
         */

        RacingGame rg = new RacingGame();

        for (int race = 1; race <= 5; race++) {
            trackComplete = false;
            currentRace = race;
            while (!trackComplete) {
                rg.startTrack();
            }
        }
        /*
         * Before 6th Race lets have right candidate for 6th race
         */
        List<String> horseNames = chooseHorsesForRace6();

        /*
         * Race among 5 tops horses from 5 races
         */
        currentRace++;
        synchronized (mutex) {
            while (!race6Begin) {
                race(horseNames);
            }
        }

        /*
         * Choose candidates for last race 7
         */
        horseNames = chooseHorsesForRace7();

        currentRace++;
        synchronized (mutex) {
            while (!race7Begin) {
                race(horseNames);
            }
        }

        printResults();

        System.exit(0);
    }

    private static void printResults() {
        // TODO Auto-generated method stub
        Iterator<Integer> iter = raceToWinners.keySet().iterator();
        while (iter.hasNext()) {
            int raceNum = iter.next();
            StringBuffer sb = new StringBuffer();
            System.out.println("Race" + raceNum + " : ");
            List<String> horses = raceToWinners.get(raceNum);
            for (int i = 0; i < 3; i++) {
                sb.append(horses.get(i));
                if (i < 2)
                    sb.append(",");
            }
            System.out.print(sb.toString());
            System.out.println();
        }
    }

    private static List<String> chooseHorsesForRace7() {
        /*
         * Adding First horse at first rank among 25 horses
         */
        List<String> winners = new ArrayList<String>();
        winners.add(raceToWinners.get(6).get(0));
        raceToWinners.put(7, winners);
        /*
         * Taking first horses from races 2 and 3
         */
        List<String> finalTrackHorses = new ArrayList<String>();
        finalTrackHorses.add(raceToWinners.get(6).get(1));// firstHorse
        finalTrackHorses.add(raceToWinners.get(6).get(2));// secondHorse
        /*
         * Rejecting all horses from race track whose first horses are at 4th
         * and 5th rank of race 6
         */
        for (int i = 1; i <= 5; i++) {
            if (raceToWinners.get(i).contains(winners.get(0))) {
                finalTrackHorses.add(raceToWinners.get(i).get(1));// thirdHorse
                finalTrackHorses.add(raceToWinners.get(i).get(2));// forth horse
            } else if (raceToWinners.get(i).contains(finalTrackHorses.get(1))) {
                finalTrackHorses.add(raceToWinners.get(i).get(1));// fifth horse
            }
        }
        return finalTrackHorses;
    }

    private static void race(List<String> horseNames) throws InterruptedException {
        if (currentRace == 6)
            race6Begin = true;
        else
            race7Begin = true;
        newTrackBegin = true;
        flag = true;
        trackComplete = false;
        while (flag) {
            if (!trackComplete) {
                /*
                 * Create thread for each horse
                 * 
                 * Here taking slot of 5 horses and keep them running in a
                 * single loop.
                 */
                if (newTrackBegin) {
                    List<String> horses = Arrays.asList(horseNames.get(0),
                            horseNames.get(1), horseNames.get(2),
                            horseNames.get(3), horseNames.get(4));
                    Race r = new Race(horses);
                    r.start();
                }
                newTrackBegin = false;
                mutex.wait(1);

            } else if (trackComplete) {
                mutex.notify();
                flag = false;
            }

        }

    }

    private static List<String> chooseHorsesForRace6() {
        List<String> lstHorses = new ArrayList<String>();
        for (int i = 1; i <= 5; i++) {
            /*
             * Take only 1st Position Holders of first 5 races
             */
            lstHorses.add(raceToWinners.get(i).get(0));
        }
        return lstHorses;
    }

    public Map<Integer, List<String>> getRaceToWinners() {
        return raceToWinners;
    }

    public static synchronized void addTrackWinnerInList(String horseName) {
        List<String> horses = raceToWinners.get(currentRace);
        if (horses == null) {
            List<String> raceHorses = new ArrayList<String>();
            raceHorses.add(horseName);
            raceToWinners.put(currentRace, raceHorses);
        } else {
            horses.add(horseName);
            raceToWinners.put(currentRace, horses);
        }
        if (raceToWinners.get(currentRace) != null
                && raceToWinners.get(currentRace).size() == 5) {
            trackComplete = true;
        }
    }

    public static boolean isTrackComplete(){
        return trackComplete;
    }

    public void startTrack() throws InterruptedException {
        // TODO Auto-generated method stub
        synchronized (mutex) {
            flag = true;
            newTrackBegin = true;
            trackComplete = false;
            while (!trackComplete) {
                /*
                 * Create thread for each horse
                 * 
                 * Here taking slot of 5 horses and keep them running in a
                 * single loop.
                 */
                    if (newTrackBegin) {
                        List<String> horses = Arrays.asList("Horse"
                                + (++frstHorseInNextRace), "Horse"
                                + (++frstHorseInNextRace), "Horse"
                                + (++frstHorseInNextRace), "Horse"
                                + (++frstHorseInNextRace), "Horse"
                                + (++frstHorseInNextRace));
                        Race r = new Race(horses);
                        r.start();
                    }
                    newTrackBegin = false;

            }

        }

    }

}


2.Horse.java

    package gamingObject;

import game.RacingGame;

public class Horse extends Thread{

    String horseName;

    public Horse(String horseName){
        this.horseName = horseName;
    }

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            try {
                sleep(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        RacingGame.addTrackWinnerInList(this.horseName);
    }

}

3.Race.java

    package gamingObject;

import game.RacingGame;

import java.util.List;

public class Race extends Thread {

    List<String> horses;
    private boolean flag = true;
    private Object obj = new Object();

    public Race(List<String> horses) {
        this.horses = horses;
    }

    public void startRace() {
        synchronized (obj) {
            run();
        }
    }

    @Override
    public void run() {
        synchronized (obj) {
            boolean newTrackBegin = true;

            while (!RacingGame.isTrackComplete()) {
                    /*
                     * Create thread for each horse
                     * 
                     * Here taking slot of 5 horses and keep them running in a
                     * single loop.
                     */
                    if (newTrackBegin) {
                        Horse h1 = new Horse(horses.get(0));
                        Horse h2 = new Horse(horses.get(1));
                        Horse h3 = new Horse(horses.get(2));
                        Horse h4 = new Horse(horses.get(3));
                        Horse h5 = new Horse(horses.get(4));
                        Thread t1 = new Thread(h1);
                        Thread t2 = new Thread(h2);
                        Thread t3 = new Thread(h3);
                        Thread t4 = new Thread(h4);
                        Thread t5 = new Thread(h5);
                        t1.start();
                        t2.start();
                        t3.start();
                        t4.start();
                        t5.start();
                        newTrackBegin = false;
                    }else{
                        if(!RacingGame.isTrackComplete()){
                            try {
                                obj.wait(10);
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }else{
                            obj.notify();
                        }

                    }

            }

        }
    }

}
I have tried this problem and solved it using following code. There is room for improvement but for me this code worked perfectly :

1.RacingGame.java
/
package game;

import gamingObject.Horse;
import gamingObject.Race;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class RacingGame {

    /**
     * @param args
     */

    public static Map<Integer, List<String>> raceToWinners = new HashMap<Integer, List<String>>();
    public static int currentRace = 1;
    public static boolean trackComplete = false;
    private static boolean newTrackBegin;
    private static boolean flag = true;
    private static boolean race6Begin = false;
    private static boolean race7Begin = false;
    private static Object mutex = new Object();
    private int frstHorseInNextRace = 0;

    public static void main(String[] args) throws InterruptedException {
        ExecutorService exeService = Executors.newFixedThreadPool(5);
        /*
         * Logic to conduct first 5 races (total horses/total track) so here
         * total horses = 25 and tracks = 5 hence initial and compolsuary races
         */

        RacingGame rg = new RacingGame();

        for (int race = 1; race <= 5; race++) {
            trackComplete = false;
            currentRace = race;
            while (!trackComplete) {
                rg.startTrack();
            }
        }
        /*
         * Before 6th Race lets have right candidate for 6th race
         */
        List<String> horseNames = chooseHorsesForRace6();

        /*
         * Race among 5 tops horses from 5 races
         */
        currentRace++;
        synchronized (mutex) {
            while (!race6Begin) {
                race(horseNames);
            }
        }

        /*
         * Choose candidates for last race 7
         */
        horseNames = chooseHorsesForRace7();

        currentRace++;
        synchronized (mutex) {
            while (!race7Begin) {
                race(horseNames);
            }
        }

        printResults();

        System.exit(0);
    }

    private static void printResults() {
        // TODO Auto-generated method stub
        Iterator<Integer> iter = raceToWinners.keySet().iterator();
        while (iter.hasNext()) {
            int raceNum = iter.next();
            StringBuffer sb = new StringBuffer();
            System.out.println("Race" + raceNum + " : ");
            List<String> horses = raceToWinners.get(raceNum);
            for (int i = 0; i < 3; i++) {
                sb.append(horses.get(i));
                if (i < 2)
                    sb.append(",");
            }
            System.out.print(sb.toString());
            System.out.println();
        }
    }

    private static List<String> chooseHorsesForRace7() {
        /*
         * Adding First horse at first rank among 25 horses
         */
        List<String> winners = new ArrayList<String>();
        winners.add(raceToWinners.get(6).get(0));
        raceToWinners.put(7, winners);
        /*
         * Taking first horses from races 2 and 3
         */
        List<String> finalTrackHorses = new ArrayList<String>();
        finalTrackHorses.add(raceToWinners.get(6).get(1));// firstHorse
        finalTrackHorses.add(raceToWinners.get(6).get(2));// secondHorse
        /*
         * Rejecting all horses from race track whose first horses are at 4th
         * and 5th rank of race 6
         */
        for (int i = 1; i <= 5; i++) {
            if (raceToWinners.get(i).contains(winners.get(0))) {
                finalTrackHorses.add(raceToWinners.get(i).get(1));// thirdHorse
                finalTrackHorses.add(raceToWinners.get(i).get(2));// forth horse
            } else if (raceToWinners.get(i).contains(finalTrackHorses.get(1))) {
                finalTrackHorses.add(raceToWinners.get(i).get(1));// fifth horse
            }
        }
        return finalTrackHorses;
    }

    private static void race(List<String> horseNames) throws InterruptedException {
        if (currentRace == 6)
            race6Begin = true;
        else
            race7Begin = true;
        newTrackBegin = true;
        flag = true;
        trackComplete = false;
        while (flag) {
            if (!trackComplete) {
                /*
                 * Create thread for each horse
                 * 
                 * Here taking slot of 5 horses and keep them running in a
                 * single loop.
                 */
                if (newTrackBegin) {
                    List<String> horses = Arrays.asList(horseNames.get(0),
                            horseNames.get(1), horseNames.get(2),
                            horseNames.get(3), horseNames.get(4));
                    Race r = new Race(horses);
                    r.start();
                }
                newTrackBegin = false;
                mutex.wait(1);

            } else if (trackComplete) {
                mutex.notify();
                flag = false;
            }

        }

    }

    private static List<String> chooseHorsesForRace6() {
        List<String> lstHorses = new ArrayList<String>();
        for (int i = 1; i <= 5; i++) {
            /*
             * Take only 1st Position Holders of first 5 races
             */
            lstHorses.add(raceToWinners.get(i).get(0));
        }
        return lstHorses;
    }

    public Map<Integer, List<String>> getRaceToWinners() {
        return raceToWinners;
    }

    public static synchronized void addTrackWinnerInList(String horseName) {
        List<String> horses = raceToWinners.get(currentRace);
        if (horses == null) {
            List<String> raceHorses = new ArrayList<String>();
            raceHorses.add(horseName);
            raceToWinners.put(currentRace, raceHorses);
        } else {
            horses.add(horseName);
            raceToWinners.put(currentRace, horses);
        }
        if (raceToWinners.get(currentRace) != null
                && raceToWinners.get(currentRace).size() == 5) {
            trackComplete = true;
        }
    }

    public static boolean isTrackComplete(){
        return trackComplete;
    }

    public void startTrack() throws InterruptedException {
        // TODO Auto-generated method stub
        synchronized (mutex) {
            flag = true;
            newTrackBegin = true;
            trackComplete = false;
            while (!trackComplete) {
                /*
                 * Create thread for each horse
                 * 
                 * Here taking slot of 5 horses and keep them running in a
                 * single loop.
                 */
                    if (newTrackBegin) {
                        List<String> horses = Arrays.asList("Horse"
                                + (++frstHorseInNextRace), "Horse"
                                + (++frstHorseInNextRace), "Horse"
                                + (++frstHorseInNextRace), "Horse"
                                + (++frstHorseInNextRace), "Horse"
                                + (++frstHorseInNextRace));
                        Race r = new Race(horses);
                        r.start();
                    }
                    newTrackBegin = false;

            }

        }

    }

}


2.Horse.java

    package gamingObject;

import game.RacingGame;

public class Horse extends Thread{

    String horseName;

    public Horse(String horseName){
        this.horseName = horseName;
    }

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            try {
                sleep(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        RacingGame.addTrackWinnerInList(this.horseName);
    }

}

3.Race.java

    package gamingObject;

import game.RacingGame;

import java.util.List;

public class Race extends Thread {

    List<String> horses;
    private boolean flag = true;
    private Object obj = new Object();

    public Race(List<String> horses) {
        this.horses = horses;
    }

    public void startRace() {
        synchronized (obj) {
            run();
        }
    }

    @Override
    public void run() {
        synchronized (obj) {
            boolean newTrackBegin = true;

            while (!RacingGame.isTrackComplete()) {
                    /*
                     * Create thread for each horse
                     * 
                     * Here taking slot of 5 horses and keep them running in a
                     * single loop.
                     */
                    if (newTrackBegin) {
                        Horse h1 = new Horse(horses.get(0));
                        Horse h2 = new Horse(horses.get(1));
                        Horse h3 = new Horse(horses.get(2));
                        Horse h4 = new Horse(horses.get(3));
                        Horse h5 = new Horse(horses.get(4));
                        Thread t1 = new Thread(h1);
                        Thread t2 = new Thread(h2);
                        Thread t3 = new Thread(h3);
                        Thread t4 = new Thread(h4);
                        Thread t5 = new Thread(h5);
                        t1.start();
                        t2.start();
                        t3.start();
                        t4.start();
                        t5.start();
                        newTrackBegin = false;
                    }else{
                        if(!RacingGame.isTrackComplete()){
                            try {
                                obj.wait(10);
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }else{
                            obj.notify();
                        }

                    }

            }

        }
    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文