Javaの並行性-概要

Javaはマルチスレッドプログラミング言語です。つまり、Javaを使用してマルチスレッドプログラムを開発できます。マルチスレッドプログラムには、同時に実行できる2つ以上のパーツが含まれ、各パーツは、特にコンピューターに複数のCPUがある場合に、使用可能なリソースを最適に利用して、異なるタスクを同時に処理できます。

定義上、マルチタスクとは、複数のプロセスがCPUなどの共通の処理リソースを共有する場合です。マルチスレッドは、マルチタスクの概念をアプリケーションに拡張し、単一のアプリケーション内の特定の操作を個々のスレッドに分割できます。各スレッドは並行して実行できます。OSは、処理時間を異なるアプリケーション間だけでなく、アプリケーション内の各スレッド間でも分割します。

マルチスレッドを使用すると、同じプログラムで複数のアクティビティを同時に進行できるように記述できます。

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

スレッドは、そのライフサイクルのさまざまな段階を通過します。たとえば、スレッドが作成され、開始され、実行されてから終了します。次の図は、スレッドの完全なライフサイクルを示しています。

以下はライフサイクルの段階です-

  • New−新しいスレッドは、新しい状態でライフサイクルを開始します。プログラムがスレッドを開始するまで、この状態のままになります。とも呼ばれますborn thread

  • Runnable−新しく生まれたスレッドが開始されると、スレッドは実行可能になります。この状態のスレッドは、そのタスクを実行していると見なされます。

  • Waiting−スレッドが別のスレッドがタスクを実行するのを待機している間に、スレッドが待機状態に移行する場合があります。別のスレッドが待機中のスレッドに実行を継続するように通知した場合にのみ、スレッドは実行可能状態に戻ります。

  • Timed Waiting−実行可能なスレッドは、指定された時間間隔で時間指定待機状態に入ることができます。この状態のスレッドは、その時間間隔が経過するか、待機中のイベントが発生すると、実行可能状態に戻ります。

  • Terminated (Dead) −実行可能なスレッドは、タスクを完了するか、その他の方法で終了すると、終了状態になります。

スレッドの優先順位

すべてのJavaスレッドには、オペレーティングシステムがスレッドがスケジュールされる順序を決定するのに役立つ優先順位があります。

Javaスレッドの優先順位は、MIN_PRIORITY(定数1)からMAX_PRIORITY(定数10)の間の範囲にあります。デフォルトでは、すべてのスレッドにNORM_PRIORITY(定数5)が優先されます。

優先度の高いスレッドはプログラムにとってより重要であり、優先度の低いスレッドの前にプロセッサ時間を割り当てる必要があります。ただし、スレッドの優先順位は、スレッドが実行される順序を保証することはできず、プラットフォームに大きく依存します。

実行可能なインターフェイスを実装してスレッドを作成する

クラスがスレッドとして実行されることを意図している場合は、実装することでこれを実現できます。 Runnableインターフェース。3つの基本的な手順に従う必要があります-

ステップ1

最初のステップとして、によって提供されるrun()メソッドを実装する必要があります。 Runnableインターフェース。このメソッドはスレッドのエントリポイントを提供し、完全なビジネスロジックをこのメソッド内に配置します。以下は、run()メソッドの簡単な構文です。

public void run( )

ステップ2

2番目のステップとして、インスタンス化する Thread 次のコンストラクタを使用するオブジェクト-

Thread(Runnable threadObj, String threadName);

ここで、threadObjは、を実装するクラスのインスタンスです。Runnable インターフェースと threadName 新しいスレッドに付けられた名前です。

ステップ3

スレッドオブジェクトが作成されたら、を呼び出すことで開始できます start()run()メソッドの呼び出しを実行するメソッド。以下はstart()メソッドの簡単な構文です-

void start();

Example

これは、新しいスレッドを作成して実行を開始する例です-

class RunnableDemo implements Runnable {
   private Thread t;
   private String threadName;

   RunnableDemo(String name) {
      threadName = name;
      System.out.println("Creating " +  threadName );
   }
   
   public void run() {
      System.out.println("Running " +  threadName );
      
      try {
      
         for(int i = 4; i > 0; i--) {
            System.out.println("Thread: " + threadName + ", " + i);
            
            // Let the thread sleep for a while.
            Thread.sleep(50);
         }
      } catch (InterruptedException e) {
         System.out.println("Thread " +  threadName + " interrupted.");
      }
      System.out.println("Thread " +  threadName + " exiting.");
   }
   
   public void start () {
      System.out.println("Starting " +  threadName );
      
      if (t == null) {
         t = new Thread (this, threadName);
         t.start ();
      }
   }
}

public class TestThread {

   public static void main(String args[]) {
      RunnableDemo R1 = new RunnableDemo("Thread-1");
      R1.start();
      
      RunnableDemo R2 = new RunnableDemo("Thread-2");
      R2.start();
   }   
}

これにより、次の結果が生成されます-

Output

Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.

スレッドクラスを拡張してスレッドを作成する

スレッドを作成する2番目の方法は、拡張する新しいクラスを作成することです。 Thread次の2つの簡単な手順を使用してクラスを作成します。このアプローチにより、Threadクラスで使用可能なメソッドを使用して作成された複数のスレッドをより柔軟に処理できます。

ステップ1

オーバーライドする必要があります run( )Threadクラスで使用可能なメソッド。このメソッドはスレッドのエントリポイントを提供し、完全なビジネスロジックをこのメソッド内に配置します。以下はrun()メソッドの簡単な構文です-

public void run( )

ステップ2

スレッドオブジェクトが作成されたら、を呼び出すことで開始できます start()run()メソッドの呼び出しを実行するメソッド。以下はstart()メソッドの簡単な構文です-

void start( );

Example

これは、スレッドを拡張するために書き直された前述のプログラムです-

class ThreadDemo extends Thread {
   private Thread t;
   private String threadName;
   
   ThreadDemo(String name) {
      threadName = name;
      System.out.println("Creating " +  threadName );
   }
   
   public void run() {
      System.out.println("Running " +  threadName );
      
      try {

         for(int i = 4; i > 0; i--) {
            System.out.println("Thread: " + threadName + ", " + i);
            
            // Let the thread sleep for a while.
            Thread.sleep(50);
         }
      } catch (InterruptedException e) {
         System.out.println("Thread " +  threadName + " interrupted.");
      }
      System.out.println("Thread " +  threadName + " exiting.");
   }
   
   public void start () {
      System.out.println("Starting " +  threadName );
      
      if (t == null) {
         t = new Thread (this, threadName);
         t.start ();
      }
   }
}

public class TestThread {

   public static void main(String args[]) {
      ThreadDemo T1 = new ThreadDemo("Thread-1");
      T1.start();
      
      ThreadDemo T2 = new ThreadDemo("Thread-2");
      T2.start();
   }   
}

これにより、次の結果が生成されます-

Output

Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.