Javaスレッド中断処理におけるinterruptedとisInterruptedの違い

スレッド中断の基本概念

マルチスレッドプログラミングにおいて、スレッドの中断は重要な機能です。スレッドを適切に中断することで、リソースの解放やエラー処理、パフォーマンス最適化などが可能になります。

フラグ変数による中断処理

public class ThreadStopExample {
    private static volatile boolean shouldStop = false;
    
    public static void main(String[] args) throws InterruptedException {
        Thread worker = new Thread(() -> {
            while(!shouldStop) {
                performTask();
            }
        });
        
        worker.start();
        Thread.sleep(2000);
        shouldStop = true;
    }
    
    private static void performTask() {
        // タスク実行処理
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

この方法ではvolatile修飾子を使用してフラグ変数を宣言しています。ラムダ式内でローカル変数を参照する場合、finalまたは実質的finalである必要があるため、インスタンス変数として宣言しています。

interruptメソッドの使用

Javaではスレッド中断をより効果的に処理するためにinterrupt()メソッドが提供されています。

public class InterruptExample {
    public static void main(String[] args) {
        Thread taskThread = new Thread(() -> {
            while(!Thread.currentThread().isInterrupted()) {
                executeOperation();
            }
        });
        
        taskThread.start();
        
        try {
            Thread.sleep(1500);
            taskThread.interrupt();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    private static void executeOperation() {
        System.out.println("処理実行中");
    }
}

sleep中の中断処理

public class SleepInterrupt {
    public static void main(String[] args) {
        Thread worker = new Thread(() -> {
            while(!Thread.currentThread().isInterrupted()) {
                try {
                    Thread.sleep(1000);
                    System.out.println("タスク実行");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        
        worker.start();
        
        try {
            Thread.sleep(3000);
            worker.interrupt();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

sleep中にinterrupt()が呼ばれるとInterruptedExceptionが発生します。この時、中断状態はクリアされるため、再度interrupt()を呼び出す必要があります。

interrupted()とisInterrupted()の違い

public class InterruptCheckDemo {
    public static void main(String[] args) {
        Thread testThread = new Thread(() -> {
            // スレッド処理
        });
        
        testThread.start();
        
        testThread.interrupt();
        System.out.println("isInterrupted: " + testThread.isInterrupted());
        System.out.println("interrupted: " + Thread.interrupted());
    }
}

isInterrupted()はスレッドの中断状態を変更せずにチェックしますが、interrupted()は静的メソッドで、現在のスレッドの中断状態をチェックした後、状態をクリアします。

タグ: Java マルチスレッド スレッド中断 interrupt isInterrupted

6月30日 21:07 投稿