この記事では、前回に引き続きJavaでスレッドを実装する方法の基本を解説します。
前回の記事では、Javaでスレッドを作る方法の一つ、スレッドを継承したクラスを作る方法について解説しました。
今回は、もう一つのスレッド作成方法である「Runnableインターフェースを実装する」方法を解説しますね。
Runnableインターフェースを実装する方法
前回の記事でスレッドとは何か等の基本については解説しました。
今回は早速本題の、Runnableインターフェースを実装する方法を解説します。
ThreadRun2(呼び出されるスレッド)
呼び出されるスレッド側のプログラムです。
Runnableインターフェースを実装(implements)しています。
runメソッドの中にスレッドに行わせたい処理を記述します。
public class ThreadRun2 implements Runnable{ public void run(){ // iが100になるまでカウントを繰り返す for(int i=0; i<100; i++){ //カウントを出力 System.out.println("Thread Count:" + i); // スリープ0.1秒待つ try { Thread.sleep(1000); } catch (InterruptedException e){ e.printStackTrace(); } } } }
ThreadCall2(呼び出し元)
こちらがスレッド呼び出し元のmainメソッドです。
スレッドを開始するには、以下3つの手順が必要です。
- ThreadRun2クラスをインスタンス化
- インスタンスを引数に入れて、Thread型のインスタンスを生成
- threadをスタート
前回の記事で紹介したThreadクラスのサブクラスを作るよりも一手間増えています。
スレッドをstartした後の処理は、スレッドとメイン処理との掛け合いのために、プリントメソッドを一定時間スリープを挟みながら繰り返しています。
public class ThreadCall2 { public static void main(String[] args){ // ThreadRun2クラスをインスタンス化 ThreadRun2 t = new ThreadRun2(); // ThreadRun2クラスを引数に入れて、Thread型のthreadインスタンスを生成 Thread thread = new Thread(t); // threadをスタート thread.start(); // iが100になるまでカウントを繰り返す for(int i=0; i<100; i++){ //カウントを出力 System.out.println("Main Count:" + i); try{ // スリープ0.1秒待つ Thread.sleep(1000); }catch (InterruptedException e){ e.printStackTrace(); } } } }
動かしてみた結果
さて、では呼び出し元プログラムのThreadCall2を実行してみます。
すると、以下の画面のように、スレッド処理と、メイン処理が平行してプリントを行っていることがわかると思います。
インターフェースで実装すると何が良いの?
前回の記事で紹介したThreadクラスのサブクラスを作る方法よりも、今回のRunnableインターフェース実装の方が若干ですが手間が増えていました。
では、なぜRunnableインターフェースで実装する方法があるのでしょうか?
答えは、Javaでは1つのクラスのサブクラスにしかなれないから(=2つ以上のクラスのサブクラスにはなれない)です。
サブクラスになるためには、「extends」を使いますが、
extends Thread, その他のクラス
となることはできません。
一方で、インターフェースは複数実装することができます。
implements Runnable, その他のインターフェース
は可能です。
そのため、Runnableインターフェースを実装する方が、コーディングの自由度は広がります。
ということで、どのようなクラスにするのか、設計によって使い分けて下さい。
ExecutorServiceを使って、複数スレッドを作成する方法はこちらの記事です。