1

I have a skeleton of my threads in the code below. I have used a simple countdown latch. I am stuck in a situation where I have Thread 1 depending on thread 2 to complete. if there is no exception, the code runs properly. But chances of exception are more. If exception occurs in thread 2 or any of the Threads, I want all the threads to stop their execution. My independent threads continue to execute even after the exception.I have also used a flag in thread 1 to check if exception occured in thread 2 i have purposely put divide by zero exception as an example to test for exeption. I am unable to find a solution to this . Please Help me..!

import java.util.concurrent.CountDownLatch;

    public class MainThread extends Thread{
        static boolean flag=false;
        final static CountDownLatch latch1= new CountDownLatch(1);
        final static CountDownLatch latch2= new CountDownLatch(1);
        final static CountDownLatch latch3= new CountDownLatch(3);
        static MainThread t1;
        static MainThread t2;
        static MainThread t3;
        static MainThread t4;
        static MainThread t5;

        public static void main(String args[]){


             t1 = new MainThread(){
                public void run(){


                    System.out.println("Waiting for Thread 2");
                    try {
                        System.out.println("THis iss before the thread 2 starts its for loop.");
                        latch2.countDown();
                        t3.start();
                        t4.start();
                        t5.start();
                        System.out.println("waiting for thread 2 to countdown");
                        latch1.await();
                        if(flag==true){
                            System.out.println("successful.");
                        }
                        else{
                            System.out.println("error.");

                        }
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println("All the dependencies resolved.");
                    System.out.println("Waiting for the remaining threads to complete their work.");
                    try {
                        latch3.await();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println("All the threads have finished doing their work. Exiting now...");
                }
            };
            Thread t2 = new MainThread(){
                public void run(){
                    System.out.println("Before Starting for loop");
                    try {

                        System.out.println("waiting for thread 1 to countdown latch2");
                        latch2.await();
                        System.out.println("Starting for loop");
                        for(int i=0;i<5;i++){
                            System.out.println("iteration: "+i);
                            try {
                                Thread.sleep(5);
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                        int x=1/0;
                        latch1.countDown();
                        System.out.println("countdown by thread2 for latch 1 done.");

                        flag=true;
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();

                    }
                    finally{
                        latch1.countDown();

                    }
                }
            };
            t3 = new MainThread(){
                public void run(){
                    System.out.println("Running Thread 3");
                    for(int i=0;i<10;i++){
                        System.out.println("iteration: "+i+ " "+t3.getName());
                        try {
                            Thread.sleep(5);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                    latch3.countDown();

                }
            };

            t4 = new MainThread(){
                public void run(){
                    System.out.println("Running Thread 4");
                    for(int i=0;i<10;i++){
                        System.out.println("iteration: "+i+ " "+t4.getName());
                        try {
                            Thread.sleep(5);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }

                    latch3.countDown();
                }
            };

            t5 = new MainThread(){
                public void run(){
                    System.out.println("Running Thread 5");
                    for(int i=0;i<10;i++){
                        System.out.println("iteration: "+i+ " "+t5.getName());
                        try {
                            Thread.sleep(5);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }

                    latch3.countDown();
                }
            };
            t1.start();
            t2.start();


        }





    }

My output is:

Before Starting for loop
waiting for thread 1 to countdown latch2
Waiting for Thread 2
THis iss before the thread 2 starts its for loop.
Starting for loop
iteration: 0
waiting for thread 2 to countdown
Running Thread 3
iteration: 0 Thread-2
Running Thread 5
iteration: 0 Thread-4
Running Thread 4
iteration: 0 Thread-3
iteration: 1
iteration: 1 Thread-3
iteration: 1 Thread-2
iteration: 1 Thread-4
iteration: 2
iteration: 2 Thread-3
iteration: 2 Thread-2
iteration: 2 Thread-4
iteration: 3
iteration: 3 Thread-3
iteration: 3 Thread-2
iteration: 3 Thread-4
iteration: 4
iteration: 4 Thread-3
iteration: 4 Thread-4
iteration: 4 Thread-2
iteration: 5 Thread-3
error.
All the dependencies resolved.
Waiting for the remaining threads to complete their work.
Exception in thread "Thread-1" java.lang.ArithmeticException: / by zero
    at ThreadProjectStructure.MainThread$2.run(MainThread.java:72)
iteration: 5 Thread-4
iteration: 5 Thread-2
iteration: 6 Thread-3
iteration: 6 Thread-4
iteration: 6 Thread-2
iteration: 7 Thread-3
iteration: 7 Thread-2
iteration: 7 Thread-4
iteration: 8 Thread-3
iteration: 8 Thread-2
iteration: 8 Thread-4
iteration: 9 Thread-3
iteration: 9 Thread-4
iteration: 9 Thread-2
All the threads have finished doing their work. Exiting now...
iamP
  • 307
  • 1
  • 3
  • 13

3 Answers3

1

Have you thought of using thread pool? If you can modify your requirement to use thread pool, in case of exception you can force the pool to shutdown and hence all the threads would be stopped.

justcurious
  • 254
  • 3
  • 15
  • I thought using latch would be simpler than pool. i can try using Pool. Is there any solution using the above code only? – iamP Sep 02 '15 at 07:13
  • I don't have an IDE right now to play around but one of the way you can try is : 1. use a volatile boolean variable and set it as false 2. If exception occurs, change its value to true 3. In all threads, for each iteration check for this variable before any processing (in your case printing the message). If value is true, break out of the loop. – justcurious Sep 02 '15 at 07:26
1

Well, with the current code you need to get your perspective right. Please define the latch variables self explanatory otherwise it will land you in confusion. Assuming following is your requirement: Proceed to other threads only if Thread 2 execution is successful.

Following is the updated code:

import java.util.concurrent.CountDownLatch;

public class MainThread extends Thread{
    static boolean flag=false;
    final static CountDownLatch waitForThread2ToFinish= new CountDownLatch(1);
    final static CountDownLatch waitForStartSignalFromThread1= new CountDownLatch(1);
    final static CountDownLatch latchForAllOtherThreads= new CountDownLatch(3);
    static MainThread t1;
    static MainThread t2;
    static MainThread t3;
    static MainThread t4;
    static MainThread t5;

    public static void main(String args[]){
        t1 = new MainThread(){
            public void run(){
                try {
                    System.out.println("Waiting for Thread 2 to finish");
                    waitForStartSignalFromThread1.countDown();
                    waitForThread2ToFinish.await();
                    if(flag==true){
                        System.out.println("Successful.");
                        t3.start();
                        t4.start();
                        t5.start();

                        System.out.println("All the dependencies resolved.");
                        System.out.println("Waiting for the remaining threads to complete their work.");
                        try {
                            latchForAllOtherThreads.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("All the threads have finished doing their work. Exiting now...");
                    }
                    else{
                        System.out.println("Error.");

                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        };
        Thread t2 = new MainThread(){
            public void run(){
                System.out.println("Before Starting for loop");
                try {

                    System.out.println("waiting for thread 1 to countdown latch2");
                    waitForStartSignalFromThread1.await();
                    System.out.println("Starting for loop");
                    for(int i=0;i<5;i++){
                        System.out.println("iteration: "+i);
                        try {
                            Thread.sleep(5);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    int x=1/0;

                    System.out.println("countdown by thread2 for latch 1 done.");

                    flag=true;
                } catch (Exception e) {
                    e.printStackTrace();

                }
                finally{
                    waitForThread2ToFinish.countDown();
                }
            }
        };
        t3 = new MainThread(){
            public void run(){
                System.out.println("Running Thread 3");
                for(int i=0;i<10;i++){
                    System.out.println("iteration: "+i+ " "+t3.getName());
                    try {
                        Thread.sleep(5);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                latchForAllOtherThreads.countDown();

            }
        };

        t4 = new MainThread(){
            public void run(){
                System.out.println("Running Thread 4");
                for(int i=0;i<10;i++){
                    System.out.println("iteration: "+i+ " "+t4.getName());
                    try {
                        Thread.sleep(5);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                latchForAllOtherThreads.countDown();
            }
        };

        t5 = new MainThread(){
            public void run(){
                System.out.println("Running Thread 5");
                for(int i=0;i<10;i++){
                    System.out.println("iteration: "+i+ " "+t5.getName());
                    try {
                        Thread.sleep(5);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                latchForAllOtherThreads.countDown();
            }
        };
        t1.start();
        t2.start();
    }
}
bprasanna
  • 2,423
  • 3
  • 27
  • 39
  • Thread 3,4 and 5 are independent threads. I thought of running them concurrently. exception handling is the only problem i am facing here. – iamP Sep 02 '15 at 07:37
  • @iampitre Then you can take them out of the `if (flag == true) ` condition. Do you want to suppress the exception? – bprasanna Sep 02 '15 at 07:39
  • Yeah I can do that. Thanks. But I am still not getting what i want. – iamP Sep 02 '15 at 07:47
0

Java doesn't provided any direct method to stop execution of running thread but it has given method to interrupt a thread. Still it's not guaranteed to stop the execution of thread , it just set the interrupt flag to true of that thread and it depends on thread to check the flag and throw interrupted exception. It's the only graceful way to stop execution of thread. you can interrupt the other thread by calling handle.interrupt()

mohit kumar
  • 179
  • 2
  • 10