views:

153

answers:

6

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.! So please anyone help me out.!*strong text

+1  A: 
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."); 
    } 
} 
Upul
bro see the question properlyI have to create two objects of the RaceHorse class and then perform a race which I did.But where to apply these thread.setName(""); and thread.getName(); functionscos both the threads will be running. And I want to know which thread stops first, thread t or thread t2.Accordingly i will display the winner and the loser.!
Badmash Ankit
Pls checkout my code.
Upul
The standard output stream usually isn't good at handling multiple threads. I wouldn't rely on it to determine the winner.
sje397
bro u did the same what i did but in different MannerBoth the threads will run and stopso both will print their namesso this will not solve my problem.!cos I have to determine which thread ends first in the Application class i.e. Runner class in my case
Badmash Ankit
Yes I 100 % agree with you. I just wanted to show the method :-)
Upul
+6  A: 

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.

sje397
+9  A: 

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!");
    }
}
cHao
+1 Nice and neat.
sje397
+1 this is a NICE way to handle this problem.
Upul
thnx brou solved my problemThank you very much.!
Badmash Ankit
A: 

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.

lorenzog
+1  A: 

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,
   }
}
fastcodejava
A: 

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

}
finnw
The spec itself says `RaceHorse` *must* extend `Thread`.
cHao