JavadocとJavaのソースコードをよく読む(InterruptedException編)

はじめに

InterruptedExceptionはJavaでよく見かけるチェック例外の1つです。

マルチスレッドでないプログラムの場合、大抵は邪魔だとしか感じないこの例外ですが、マルチスレッドプログラミングでは抑えておかないと困ったことになります。

というわけで、今回はInterruptedExceptionを詳しく見ていきます。

InterruptedExceptionとは

以下、Javadocの抜粋ですが、

Thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is interrupted, either before or during the activity.

スレッドが

  • waiting
  • sleeping
  • occupied(ここではactiveという意味合いのよう)

の状態で、処理前か処理中に割り込まれた時に投げられる例外ということです。

確かにwait/sleepいずれのメソッドもInterruptedExceptionをthrowするようになっています。

Throws:
InterruptedException – if any thread has interrupted the current thread.

Throws:
InterruptedException – if any thread interrupted the current thread before or while the current thread was waiting for a notification.

とりあえずInterruptedExceptionの定義はわかりました。

つづいてInterruptedExceptionを投げるJavaのAPIのソースコードを見てみます。

BlockingQueueの実装を見てみる

BlockingQueueは名前の通り、要素の取得/挿入時にブロックするキューです。今回はBlockingQueueの実装の1つであるLinkedBlockingQueueのtakeメソッドのソースコードをみてみます。

takeメソッドのJavadocは以下の通りで、要素がなかったら来るまで待機するメソッドで、割り込み時にInterruptedExceptionを投げます。

Retrieves and removes the head of this queue, waiting if necessary until an element becomes available.

Throws:
InterruptedException – if interrupted while waiting

IDE(Intelij IDEA)がデコンパイルしたコードでtakeの中身みてるとこんな感じです。

public E take() throws InterruptedException {
        boolean var2 = true;
        AtomicInteger var3 = this.count;
        ReentrantLock var4 = this.takeLock;
        var4.lockInterruptibly();

        Object var1;
        int var8;
        try {
            while(var3.get() == 0) {
                this.notEmpty.await();
            }

whileの中が気になりますね。なので更にnotEmpty.await()の実装みてみます。

public final void await() throws InterruptedException {
            if(Thread.interrupted()) {
                throw new InterruptedException();
            } else {
                AbstractQueuedSynchronizer.Node var1 = this.addConditionWaiter();

Thread.interrupted()でスレッドの割り込みステータスのチェック後に、InterruptedExceptionをスローしていますね。

なので、JavaのAPIでInterruptedExceptionを投げるメソッドも実態としては、自身で割り込みステータスのチェックをやってたりするんですね。

まとめ

InterruptedExceptionは処理前か処理中に割り込まれた時に投げられる例外で、JavaのAPIの実装でも自身の割り込みステータスを明示的にチェックしてInterruptedExceptionをスローするものもあるということがわかりました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA