未来エンジニア養成所Blog

プログラミングを皆に楽しんでもらうための情報をお届けします。

【Java】マルチスレッド Part2

title

前回に引き続きマルチスレッドの解説です。

前回の記事はこちら。 phoeducation.work


スレッドの状態

プログラム内の1つ1つの動作をスレッドと言いますが、マルチスレッドの機能を利用することで、あたかも同時に複数の動作をさせることができます。

これらのスレッドにはそれぞれにスレッドが生成されてから終了するまでの5つの状態があります。

スレッドの状態を管理するには、JavaVMの機能の一部であるスレッドスケジューラです。

プログラマはスレッドの状態を変えるメソッドを使ってスレッドの状態を変更することができますが、スレッドの状態を管理するのは、あくまでスレッドスケジューラであり、スレッドの状態を制御するメソッドはスレッドの状態に影響を与えることしかできません。

次の表と図は、5つのスレッドの状態とスレッドの状態がどのように変化していくか(状態遷移)を示しています。


【スレッドの状態遷移】

スレッドの状態 説明
初期状態 スレッドが生成されたがstart()
が呼び出されていない状態
まだ生存しているとは言わない
実行可能状態 スレッドが生成され、実行の機会
が与えられるのを待っている状態
実行中状態 スレッドが実行され、処理を行っ
ている状態
待機状態/ブロック状態
スリープ状態
スレッドは生存しているが、実行
対象の資格を有していない
特定のイベントが発生すれば
実行可能状態になる
終了状態 run()メソッドの処理が終わり、
スレッドが終了した状態


状態遷移


最初にスレッドクラスのオブジェクトがインスタンス化されることでスレッドが生成されます。

まだstart()メソッドも呼ばれず実行されてない状態を初期状態と言います。

この状態は生存しているとは言いません。

初期状態のスレッドはstart()メソッドが呼び出されると実行の機会を待っている実行可能状態となります

まだ実行されている状態ではないスタンバイ状態です。

実行可能状態のスレッドの中からスレッドスケジューラが選択したスレッドが実行されます。

この実行されているスレッドを実行中状態と言います。

実行中のスレッドは、スレッドの制御をするメソッドなどによって実行可能状態に戻ったり、待機状態、ブロック状態、スリープ状態に変わります。

またrun()メソッドの処理が終了した場合は終了状態になります。

待機状態、ブロック状態、スリープ状態はスレッドを制御するメソッドによってこの状態になるもので、実行可能状態になる可能性のあるスレッドの状態です。

必ず実行可能状態になった後で実行中状態になります。

これらのスレッドの状態はあくまでスレッドスケジューラが管理しています。

スレッドの状態を管理するメソッドを使用することができますが、影響を与える程度と理解をしておきましょう。

言いかえるとプログラマはスレッドの状態を完全に制御できるわけではありません。


スレッドの優先順位

複数のスレッドが競合した場合、どのスレッドから実行するかはJavaVMが制御しているためプログラマが完全に制御することはできませんが、Threadクラスのメソッドを使用してある程度スレッドの優先順位を設定することができます。

優先順位は1から10まで設定することができ、新たに作られたスレッドの優先順位はデフォルトで5と決められています。


【Threadクラスのメソッド】

メソッド名 説明
public staic Thread currentThread() 現在実行中のスレッドオブジェクトを取得する
public final int getPriority() スレッドの優先度を返す
public final void setPriority(int newPriority) スレッドの優先順を変更する。1〜10を引数に指定。デフォルトは5


【setPriority()の引数に指定できる定数】

変数名 説明
public static final int MIN_PRIORITY 最小の優先度。1を表す
public static final int NORM_PRIORITY デフォルトの優先度。5を表す
public static final int MAX_PRIORITY 最大の優先度。10を表す


現在実行中のスレッドを取得するメソッドとして、ThreadクラスのcurrentThread()メソッドがあります。

これはstaticメソッドなので、Thread.currentThread()と記述します。

現在使用中のメソッドの優先順位を調べるには、getPriority()メソッドを使用します。

現在使用中のスレッドに優先順位を設定するには、setPriority()メソッドを使用します。

このメソッドの引数には図のような定数を指定するか、1から10までに数値を指定します。


【スレッドの優先順位を設定する】

public class ThreadSample03 {
    public static void main(String[] args) {
        Thread mainThread = Thread.currentThread();
        System.out.println("mainThreadの優先順位:"+ mainThread.getPriority());

        MyThread3 mt = new MyThread3();
        mt.setPriority(Thread.MAX_PRIORITY);
        System.out.println("MyThread3の優先順位:"+ mt.getPriority());
        mt.start();

        for(int i = 1; i <= 10 ; i++){
            System.out.println(i + "回目のmain()の処理です");
        }
    }
}
class MyThread3 extends Thread{
    public void run(){
        for(int i = 1; i <= 10 ; i++){
            System.out.println(i + "回目のMyThread3の処理です");
        }
    }
}


実行結果

mainThreadの優先順位:5
MyThread3の優先順位:10
1回目のmain()の処理です
2回目のmain()の処理です
3回目のmain()の処理です
1回目のMyThread3の処理です
4回目のmain()の処理です
5回目のmain()の処理です
2回目のMyThread3の処理です
3回目のMyThread3の処理です
4回目のMyThread3の処理です
6回目のmain()の処理です
5回目のMyThread3の処理です
7回目のmain()の処理です
6回目のMyThread3の処理です
7回目のMyThread3の処理です
8回目のmain()の処理です
8回目のMyThread3の処理です
9回目のMyThread3の処理です
9回目のmain()の処理です
10回目のmain()の処理です
10回目のMyThread3の処理です


3行目のThread mainThread = Thread.currentThread();でmainスレッドオブジェクトを取得し、4行目のmainThread.getPriority()でmainスレッドの優先順位を取得しています。

スレッドの優先順位はデフォルトで5なので、「mainThreadの優先順位:5」と表示されます。

6行目で新しいThreadオブジェクトを生成し、7行目のmt.setPriority(Thread.MAX_PRIORITY);で優先順位を最高に設定し、9行目でスレッドをスタートします。

mainスレッドとMyThread3スレッドがマルチスレッドとして動きますが、mainスレッドの優先順位は5、MyThread3の優先順位は10に設定しているのですが、MyThread3が必ず優先的に実行されるわけではありません。


「マルチスレッド Part3」へ続きます。 phoeducation.work


参考図書



独学で挫折しそうになったら、オンラインプログラミングスクール
未来エンジニア養成所Logo



あわせて学習したい

phoeducation.work phoeducation.work