-1
public class Threading extends Thread {
    @Override
    public void run(){
        for (int i=0;i<=5;i++){
            System.out.println(Thread.currentThread().getName()+" reached "+i+" metres");
            if(i==5){
                System.out.println("WINNER IS  "+Thread.currentThread().getName().toUpperCase(Locale.ENGLISH));              
                break;
            }
        }
    }
    public static void main(String[] args) {
        Threading t1=new Threading();
        Threading t2=new Threading();
        Threading t3=new Threading();
        t1.setName("Mohit");
        t2.setName("Hary");
        t3.setName("Himanshu");
        t1.start();
        t2.start();
        t3.start();
    }
}

I want to print the name of the thread which reaches the 5 meters first and then go out of the loop. But what is happening with this code is that the the for loop is running until each thread reaches 5 meters and printing the name of all the threads as they reach the 5 meters. Please tell me why is this happening and how can i correct it ?

Gray
  • 115,027
  • 24
  • 293
  • 354
jack reacher
  • 227
  • 1
  • 3
  • 10
  • 3
    Each thread runs the loop *independently* of the others. When one `break`s from it, the others are unaffected. – John Bollinger Jan 21 '17 at 19:06
  • Thanks for the answer . Can You show me how can i stop the threads in my current code ? @JohnBollinger – jack reacher Jan 21 '17 at 19:10
  • maybe use an `AtomicBoolean` – luk2302 Jan 21 '17 at 19:14
  • There's really no point in stopping threads in this example, as the for loops finish almost immediately. Generally though [`Thread.interrupt` is used to stop a Thread](http://stackoverflow.com/a/10962613/5517612). – Todd Sewell Jan 21 '17 at 19:16
  • @jackreacher Its already been explained why this isn't working. For how to actually do it, see http://stackoverflow.com/questions/5028095/how-to-know-which-thread-completes-execution-first-out-of-two-threads – Gabe Sechan Jan 21 '17 at 19:16
  • `Thread.interrupt()` is not used by itself to stop a thread, @ToddSewell. The thread to be stopped must cooperate. Moreover, an approach based on `Thread.interrupt()` would not necessarily solve the problem of ensuring that only one thread declares itself the winner. – John Bollinger Jan 21 '17 at 19:22
  • @JohnBollinger You're right, as explained in the answer I linked. And you're right that that won't solve this specific issue, I was only replying to OP's question about stopping threads. – Todd Sewell Jan 21 '17 at 19:26

2 Answers2

0

How about using an AtomicBoolean in the following way:

public static class Threading extends Thread {
    private AtomicBoolean raceFinished;

    public Threading(AtomicBoolean raceFinished) {
        this.raceFinished = raceFinished;
    }

    @Override
    public void run() {
        for (int i = 0; i <= 5; i++) {
            System.out.println(Thread.currentThread().getName() + " reached " + i + " metres");
            if (i == 5) {
                if (raceFinished.getAndSet(true)) {
                    break;
                }
                System.out.println("WINNER IS  " + Thread.currentThread().getName().toUpperCase(Locale.ENGLISH));
                break;
            }
        }
    }

    public static void main(String[] args) {
        AtomicBoolean raceFinished = new AtomicBoolean(false);
        Threading t1 = new Threading(raceFinished);
        Threading t2 = new Threading(raceFinished);
        Threading t3 = new Threading(raceFinished);
        t1.setName("Mohit");
        t2.setName("Hary");
        t3.setName("Himanshu");
        t1.start();
        t2.start();
        t3.start();
    }
}

If you do not want the "race" to continue after the winner was found, then add the following in the beginning of the loop:

if (raceFinished.get()) {
    break;
}
luk2302
  • 55,258
  • 23
  • 97
  • 137
  • thanks alot for helping me out. i am a beginner can u direct me to some links where i can learn more about multithreading . – jack reacher Jan 22 '17 at 07:37
  • @jackreacher Not really. But I think multithreading is the single worst concept / technique to get yourself into as a beginner - almost anything else makes more sense. – luk2302 Jan 22 '17 at 12:13
  • 1
    Using `raceFinished.compareAndSet(false, true)` is a little more efficient because that's what `getAndSet(...)` uses under the covers just in a loop. – Gray Jan 28 '17 at 23:47
0

But what is happening with this code is that the the for loop is running until each thread reaches 5 meters and printing the name of all the threads as they reach the 5 meters. Please tell me why is this happening ...

Each of the threads is running independently. All they are doing is counting to 5 and printing WINNER and they have no idea what the other threads are doing or if any have "won" before them. If you want just one thread to be the winner then they need to share some sort of state so they know which one is the winner.

... and how can i correct it ?

I think @luk2302's answer, with a shared AtomicBoolean is a good way to correct the problem. A single AtomicBoolean is created by the main thread and passed into all of the sub-threads.

final AtomicBoolean raceFinished = new AtomicBoolean(false);
Threading t1 = new Threading(raceFinished);
Threading t2 = new Threading(raceFinished);
Threading t3 = new Threading(raceFinished);

Then as each thread runs to the end of the loop, only one thread is able to set the AtomicBoolean to be true and declare itself the winner.

for (int i = 0; i < 5; i++) {
    // ...
}
// i == 5 here
// this is an atomic operation and will succeed only for 1 thread
if (raceFinished.compareAndSet(false, true)) {
    // this is only printed if raceFinished was false beforehand
    System.out.println("WINNER IS  " + Thread.currentThread().getName());
}

How does this work? The single AtomicBoolean is shared between all of the threads. Inside of it is a volatile boolean field and logic to ensure atomic updates to the boolean. The volatile puts up memory barriers so that the threads can appropriately see and update the shared boolean field appropriately. The reason this is important is because the performance of threaded programs rely heavily on local CPU caches so they can run independently and get high performance.

Hope this helps.

Gray
  • 115,027
  • 24
  • 293
  • 354