tanish-kr's learning log

Learning output log

Java

スレッド

スレッドとは

スレッドとは、プログラムを実行している主体です。すべてのプログラムはスレッドによって実行されています。

マルチスレッド

Javaでは複数のスレッドを同時に実行することができる。 マルチスレッドでは通常、時分割処理という方法が用いられている。 時分割処理とは、短い時間間隔で実行する処理を切り替える方法で、複数の処理を頻繁に切り替えて実行することで、仮想的に複数の処理を同時に実行しているように見せかけています。

スレッドのライフサイクル

Lifecycle

  • 初期状態 新しいスレッドを作成した状態で、この状態ではまだスレッドは動作していない。startメソッドで実行可能状態となる

  • 実行可能状態 スレッドが動作している状態で、実行中実行準備完了の2つの状態にわけられます。

    • 実行中 時分割処理によって実際にCPUによって処理が実行されている状態。CPUの数に応じて実行中のスレッドの数が決まる

    • 実行準備完了 CPU時間が割り当てられるのを待機している状態

  • ブロック状態 ディスクの入出力操作や、スレッドの排他制御や同期処理などにより、スレッドの動作が一時的に休止している状態。ブロック状態の原因が解消されれば実行可能状態に戻る

  • 終了状態 スレッドの処理が終了した状態

スレッドの実行

Threadクラスを継承する方法

class CountDownThread extends Thread {

   private String name;

   public CountDownThread(String name) {
     this.name = name;
   }

   public void run() {
    for (int i = 3; i >= 0 ; i--) {
      try {
        sleep(1000);
      } catch (InterruptedException e) {}
      System.out.println(name + " : " + i);
    }
  }

  public static void main(String[] args) {
    // Thread 1のインスタンス生成
    CountDownThread t1 = new CountDownThread("thread 1");
    // Thread 2のインスタンス生成
    CountDownThread t2 = new CountDownThread("thread 2");
    t1.start();
    t2.start();
  }

}

Runnableインターフェースを実装する方法

public class CountDownTest implements Runnable {

   private String name;

   public CountDownTest(String name) {
     this.name = name;
   }

   public void run() {
    for (int i = 3; i >= 0 ; i--) {
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {}
      System.out.println(name + " : " + i);
    }
  }

  public static void main(String[] args) {
    CountDownTest cdt1 = new CountDownTest("thread 1");
    CountDownTest cdt2 = new CountDownTest("thread 2");
    Thread t1 = new Thread(cdt1);
    Thread t2 = new Thread(cdt2);
    t1.start();
    t2.start();
  }

}

使い分けとして、runメソッドをオーバライドするだけのシンプルなスレッドならRunnableインターフェースを利用し、Threadクラスを継承する場合はrun以外もオーバライドしてスレッドの振る舞いを変えたい場合のみに使用することが推奨されている。

スレッドの排他制御

複数のスレッドが同じオブジェクトを同時に操作すると、予期せぬ動作をすることがあります。そのため、複数のスレッドの動作を制御するためにsynchronizedブロックが用意されている.

volatile変数

複数のスレッドで共有される変数をvolatile宣言することにより、その変数の一貫性を保つ。volatile変数は、スレッドからアクセスがあるたびに、必ず共有メモリ上の変数の値とスレッドの作業コピー上の値とを一致させます。

参考

http://www.techscore.com/tech/Java/JavaSE/Thread/index/