Java - Thread Interrupts

[Updated: Feb 7, 2017, Created: Mar 25, 2016]

An interrupt is the indication to a thread that it should stop what it is doing and do something else.

Interrupts are operating system level mechanism to signal threads about some particular event.

In Java Thread#interrupt() method is used to interrupt a thread

Within the interrupted thread, Thread.currentThread().isInterrupted() can be used to find interrupted state. OR if the thread is blocked on Object.wait(..), Thread.join(...) or Thread.sleep(..), InterruptedException will be thrown. That means all method calls which throws InterruptedException will receive this exception when this thread is interrupted.

Following examples show how to use this feature.


Using Interrupt to terminate a thread

public class ThreadInterruptExample {
    public static void main (String[] args) throws InterruptedException {
        Task task1 = new Task();
        Thread thread1 = new Thread(task1);
        thread1.start();
        while (true){
            if(Math.random()>0.5){
                thread1.interrupt();
                break;
            }
            TimeUnit.MILLISECONDS.sleep(1);
        }
    }

    private static class Task implements Runnable {

        @Override
        public void run () {
            int c = 0;

            while (true) {

                System.out.println("task running .. " + ++c);
                if (Thread.currentThread()
                          .isInterrupted()) {
                    System.out.println("interrupted flag=true");
                    terminate();
                    return;
                }
                try {
                    TimeUnit.MICROSECONDS.sleep(1);
                } catch (InterruptedException e) {
                    System.out.println("interrupted exception ");
                    terminate();
                    return;
                }
            }

        }

        private void terminate () {
            System.out.println("Terminating task");
        }
    }
}

Output:

Running above example multiple times can result in two outputs:

task running .. 1
interrupted exception
Terminating task

or

task running .. 1
task running .. 2
task running .. 3
interrupted flag=true
Terminating task

Since I tested the above on a machine having multiple cores, the main thread and the thread doing the task can truly run in parallel, that's the reason we should always use the method Thread.isInterrupted besides catching the InterruptedException.


Swing animation interrupt example

Following Swing example demonstrates how to use interrupts to make an alternate decision.

public class ThreadInterruptSwingDemo {
    public static void main (String[] args) {
        JFrame frame = new JFrame("Interrupt Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(new Dimension(500, 500));
        frame.add(createAnimationContainer());
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private static Component createAnimationContainer () {
        JPanel panel = new JPanel(new BorderLayout());
        AnimatedPanel animatedPanel = new AnimatedPanel();
        panel.add(animatedPanel);
        JButton button = new JButton("Reverse");
        panel.add(button, BorderLayout.SOUTH);
        button.addActionListener(e -> {
            animatedPanel.getThread().interrupt();

        });
        return panel;
    }

    private static class AnimatedPanel extends JComponent {
        private int angle = 0;
        boolean clockwise = true;
        private Thread thread;

        AnimatedPanel () {
            startAnimation();
        }

        private void startAnimation () {
            thread = new Thread(() -> {
                while (true) {
                    angle++;
                    if (angle >= 360) {
                        angle = 0;
                    }
                    if(thread.isInterrupted()){
                        clockwise = !clockwise;
                    }
                    //no need to create EDT
                    repaint();
                    try {
                        TimeUnit.MILLISECONDS.sleep(10);
                    } catch (InterruptedException e) {
                        clockwise = !clockwise;

                    }
                }
            });
            thread.start();
        }

        @Override
        public void paint (Graphics g) {
            g.setColor(Color.MAGENTA);
            g.fillArc(10, 10, 400, 400, clockwise? -angle: angle, 30 );
        }

        public Thread getThread () {
            return thread;
        }
    }
}

Output:

Initially the circular sector rotates in clockwise direction

Clicking on 'Reverse' button will always change the rotation direction.

Example Project

Dependencies and Technologies Used :

  • JDK 1.8
  • Maven 3.0.4

Java Thread Interrupt Example Select All Download
  • java-thread-interrupt
    • src
      • main
        • java
          • com
            • logicbig
              • example

See Also