Interrupting thread loops in Java

I am trying to understand how threads work in Java and are currently exploring how to implement closed threads that can be undone. Here is the code:

public static void main(String[] args) throws Exception {
    Thread t = new Thread() {
        @Override
        public void run() {
            System.out.println("THREAD: started");
            try {
                while(!isInterrupted()) {
                    System.out.printf("THREAD: working...\n");
                    Thread.sleep(100);
                }
            } catch(InterruptedException e) {
                // we're interrupted on Thread.sleep(), ok

                // EDIT
                interrupt();

            } finally {
                // we've either finished normally
                // or got an InterruptedException on call to Thread.sleep()
                // or finished because of isInterrupted() flag

                // clean-up and we're done
                System.out.println("THREAD: done");
            }               
        }
    };

    t.start();
    Thread.sleep(500);
    System.out.println("CALLER: asking to stop");
    t.interrupt();
    t.join();
    System.out.println("CALLER: thread finished");
}

The created thread, as a rule, is interrupted sooner or later. So I check isInterrupted box () to decide whether or not I need to continue, and catch InterruptedExceptionto handle when I perform the waiting operation ( sleep, join, wait).

The things I would like to clarify are as follows:

  • Can the interrupt mechanism be used for this kind of task? (compared to volatile boolean shouldStop)
  • Is this the right decision?
  • Is it normal that I swallow an InterruptedException? I am not interested in what kind of code this is, where someone asked my thread to interrupt.
  • ? ( )

interrupt() catch InterruptedException.

+5
4

. 3:

: ? (, ) .

InterruptedException:

  • , .
  • Thread.currentThread.interrupt() . , , , ,

InterruptedException , . , .

" " , , , , - ?

, . , , - .

, , : http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html

+4
  • , . , Thread/Runnable . stop Runnable, . , , , .
  • , - InterruptedException: Thread.currentThread().interrupt();
  • ,
  • ,
+2

1) volatile ( , ), Java Concurrency . InterruptedExceptions.

2)

3) , . , , , , . ( , , , , , , , , .)

4) no

+1

, . Thread.currentThread().interrupt() . , , :

public class MyThread extends Thread {
    private static boolean correct = true;

    @Override
    public void run() {
        while (true) {
            // Do Something 1
            for (int i = 0; i < 10; i++) { // combined loop
                // Do Something 2
                try {
                    Thread.sleep(100);
                } catch (InterruptedException ex) {
                    if (correct)
                        Thread.currentThread().interrupt(); // reinterrupting
                    System.out.println("First Catch");
                    break; // for
                }
            }
            try {
                // Do Something 3
                System.out.print("before sleep, ");
                Thread.sleep(1000);
                System.out.print("After sleep, ");
            } catch (InterruptedException ex) {
                if (correct)
                    Thread.currentThread().interrupt();
                System.out.println("Second catch");
                break; // while
            }
        }
        System.out.println("Thread closing");
    }

    private static void test() throws InterruptedException {
        Thread t = new MyThread();
        t.start();
        Thread.sleep(2500);
        t.interrupt();
        t.join();
        System.out.println("End of Thread");
    }

    public static void main(String[] args)
            throws InterruptedException {
        test();
        correct = false; // test "bad" way
        test();
    }
}

Another thing Interruptionsdoes not always work when waiting InputStreams. Then you can use (for some) InterruptedIOException, but this will not always work. To understand these cases, you can try this piece of code:

public class Mythread extends Thread {
    private InputStream in;

    public Mythread(InputStream in) {
        this.in = in;
    }

    @Override
    public void interrupt() {
        super.interrupt();
        try {
            in.close(); // Close stream if case interruption didn't work
        } catch (IOException e) {}
    }

    @Override
    public void run() {
        try {
            System.out.println("Before read");
            in.read();
            System.out.println("After read");
        } catch (InterruptedIOException e) { // Interruption correctly handled
            Thread.currentThread().interrupt();
            System.out.println("Interrupted with InterruptedIOException");
        } catch (IOException e) {
            if (!isInterrupted()) { // Exception not coming from Interruption
                e.printStackTrace();
            } else { // Thread interrupted but InterruptedIOException wasn't handled for this stream
                System.out.println("Interrupted");
            }
        }
    }

    public static void test1() // Test with socket
            throws IOException, InterruptedException {
        ServerSocket ss = new ServerSocket(4444);
        Socket socket = new Socket("localhost", 4444);
        Thread t = new Mythread(socket.getInputStream());
        t.start();
        Thread.sleep(1000);
        t.interrupt();
        t.join();
    }

    public static void test2() // Test with PipedOutputStream
            throws IOException, InterruptedException { 
        PipedInputStream in = new PipedInputStream(new PipedOutputStream());
        Thread t = new Mythread(in);
        t.start();
        Thread.sleep(1000);
        t.interrupt();
        t.join();
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        test1();
        test2();
    }
}
+1
source

All Articles