Javaでスレッドを実現する3つの方法と対比_動力ノードJava学院の整理


Javaでスレッドを作成するには主に3つの方法があります。
一、Thread類を継承してスレッド類を作成する
(1)Thread類のサブクラスを定義し、このタイプのrun方法を書き換えます。このrun方法の方法体はスレッドの完成すべき課題を表しています。従って、run()方法を実行体と呼びます。
(2)Threadサブクラスの例を作成すると、スレッドオブジェクトが作成されます。
(3)スレッドオブジェクトのstart()メソッドを呼び出してスレッドを起動します。

package com.thread; 
public class FirstThreadTest extends Thread{ 
  int i = 0; 
  //  run  ,run              
  public void run() 
  { 
    for(;i<100;i++){ 
    System.out.println(getName()+" "+i); 
    } 
  } 
  public static void main(String[] args) 
  { 
    for(int i = 0;i< 100;i++) 
    { 
      System.out.println(Thread.currentThread().getName()+" : "+i); 
      if(i==20) 
      { 
        new FirstThreadTest().start(); 
        new FirstThreadTest().start(); 
      } 
    } 
  } 
} 
上記のコードの中でThread.current Thread()方法は現在実行中のスレッドオブジェクトを返します。GetName()メソッドは、この方法を呼び出すスレッドの名前を返します。
二、Runnableインターフェースでスレッドクラスを作成する
(1)runnableインターフェースの実装クラスを定義し、このインターフェースのrun()方法を書き換え、このrun()方法の方法体は同じスレッドのスレッド実行体である。
(2)Runnable実装クラスの例を作成し、この例に従ってThreadのtargetとしてThreadオブジェクトを作成し、このThreadオブジェクトこそが真のスレッドオブジェクトである。
(3)スレッドオブジェクトのstart()メソッドを呼び出してスレッドを起動します。
例のコードは以下の通りです

package com.thread; 
public class RunnableThreadTest implements Runnable 
{ 
  private int i; 
  public void run() 
  { 
    for(i = 0;i <100;i++) 
    { 
      System.out.println(Thread.currentThread().getName()+" "+i); 
    } 
  } 
  public static void main(String[] args) 
  { 
    for(int i = 0;i < 100;i++) 
    { 
      System.out.println(Thread.currentThread().getName()+" "+i); 
      if(i==20) 
      { 
        RunnableThreadTest rtt = new RunnableThreadTest(); 
        new Thread(rtt,"   1").start(); 
        new Thread(rtt,"   2").start(); 
      } 
    } 
  } 
} 
三、CallableとFutureでスレッドを作成する
(1)Callableインターフェースの実装クラスを作成し、スレッド実行体としてのcall()方法を実現し、リターン値がある。
(2)Callable実装クラスの例を作成し、CallableオブジェクトをFutureTaskクラスを使用して包装し、このFutureTaskオブジェクトはCallableオブジェクトのcall()方法の戻り値をカプセル化している。
(3)FutureTaskオブジェクトをThreadオブジェクトとするtargetで新規スレッドを作成して起動する。
(4)FutureTaskオブジェクトのget()メソッドを呼び出して、サブスレッド実行終了後の戻り値を取得する。
インスタンスコード:

package com.thread; 
import java.util.concurrent.Callable; 
import java.util.concurrent.ExecutionException; 
import java.util.concurrent.FutureTask; 
public class CallableThreadTest implements Callable<Integer> 
{ 
  public static void main(String[] args) 
  { 
    CallableThreadTest ctt = new CallableThreadTest(); 
    FutureTask<Integer> ft = new FutureTask<>(ctt); 
    for(int i = 0;i < 100;i++) 
    { 
      System.out.println(Thread.currentThread().getName()+"      i  "+i); 
      if(i==20) 
      { 
        new Thread(ft,"       ").start(); 
      } 
    } 
    try 
    { 
      System.out.println("       :"+ft.get()); 
    } catch (InterruptedException e) 
    { 
      e.printStackTrace(); 
    } catch (ExecutionException e) 
    { 
      e.printStackTrace(); 
    } 
  } 
  @Override 
  public Integer call() throws Exception 
  { 
    int i = 0; 
    for(;i<100;i++) 
    { 
      System.out.println(Thread.currentThread().getName()+" "+i); 
    } 
    return i; 
  } 
} 
二、スレッドを作成する三つの方式の対比
Runnable、Callableインターフェースを実現する方式でマルチスレッドを作成する場合、利点は:
スレッドクラスは、RunnableインターフェースまたはCallableインターフェースを実現するだけでなく、他のクラスを継承することもできます。
このように、複数のスレッドは同一のtargetオブジェクトを共有することができるので、同じリソースを複数の同じスレッドで処理する場合には非常に適しており、CPU、コード、データを分離して、明瞭なモデルを形成し、対象に向けた思想をより良く体現することができる。
劣勢は:
プログラムはやや複雑で、現在のスレッドにアクセスするには、Thread.current Thread()の方法が必要です。
Thread類を継承する方式でマルチスレッドを作成する場合の利点は:
編纂は簡単で、現在のスレッドにアクセスする必要があれば、Thread.current Thread()の方法を使わずに、そのままthisを使って現在のスレッドを取得することができます。
劣勢は:
スレッド類はすでにThread類を引き継いでいますので、他の親類を引き継ぐことはできません。
以上、小编で绍介したJavaでスレッドを実现する3つの方法と対比です。動力ノードJava学院は整理して、みんなに助けがあることを望んで、もしみんなはいかなる疑問があるならば、メッセージを下さい。ここでも私たちのサイトを応援してくれてありがとうございます。