ホームページ >Java >&#&チュートリアル >Java でスレッドを作成する 3 つの方法 (コード) の紹介

Java でスレッドを作成する 3 つの方法 (コード) の紹介

不言
不言転載
2019-02-01 11:21:292835ブラウズ

この記事では、Java でスレッドを作成する 3 つの方法 (コード) を紹介します。必要な方は参考にしていただければ幸いです。

Java でスレッドを作成する場合は、通常、次の 3 つの方法があります。

  1. #Thread クラスを継承します。 #implementation Runnable インターフェイス;

  2. Callable と Future を使用してスレッドを作成します。

  3. 1. Thread クラスを継承する

Thread クラスを継承する場合は、run メソッドをオーバーライドし、必要なタスクを定義する必要があります。 run メソッドで実行されます。

class MyThread extends Thread{
    private static int num = 0;
     
    public MyThread(){
        num++;
    }
     
    @Override
    public void run() {
        System.out.println("主动创建的第"+num+"个线程");
    }
}
独自のスレッド クラスを作成した後、スレッド オブジェクトを作成し、start() メソッドを通じてスレッドを開始できます。 run() メソッドは、スレッドを開始するために呼び出されるわけではないことに注意してください。 run メソッドが呼び出される場合、それはメインスレッドで run メソッドを実行することと同じになります。現時点では、通常のメソッド呼び出しと何の違いもありません。定義されたタスクを実行するために新しいスレッドが作成されます。

public class Test {
    public static void main(String[] args)  {
        MyThread thread = new MyThread();
        thread.start();
    }
}
 
 
class MyThread extends Thread{
    private static int num = 0;
     
    public MyThread(){
        num++;
    }
     
    @Override
    public void run() {
        System.out.println("主动创建的第"+num+"个线程");
    }
}

上記のコードでは、start() メソッドを呼び出すことで、新しいスレッドが作成されます。 start() メソッド呼び出しと run() メソッド呼び出しの違いを区別するには、次の例を参照してください。

public class Test {
    public static void main(String[] args)  {
        System.out.println("主线程ID:"+Thread.currentThread().getId());
        MyThread thread1 = new MyThread("thread1");
        thread1.start();
        MyThread thread2 = new MyThread("thread2");
        thread2.run();
    }
}
 
 
class MyThread extends Thread{
    private String name;
     
    public MyThread(String name){
        this.name = name;
    }
     
    @Override
    public void run() {
        System.out.println("name:"+name+" 子线程ID:"+Thread.currentThread().getId());
    }
}

実行結果:


## 出力結果から次の結論が導き出されます。

1) thread1 と thread2 のスレッド ID は異なり、thread2 とメイン スレッド ID は同じです。これは、run メソッドを呼び出していることを示しています。新しいスレッドは作成されませんが、メインスレッドで run メソッドを直接実行することは通常のメソッド呼び出しと変わりません。

2) thread1 の start メソッド呼び出しは thread2 の run メソッドより前に呼び出されます。 thread2 の run メソッド呼び出しに関連する情報が最初に出力され、新しいスレッドの作成プロセスがメイン スレッドの後続の実行をブロックしないことを示します。

2. Runnable インターフェイスの実装

Java でスレッドを作成するときに Thread クラスを継承するだけでなく、Runnable インターフェイスを実装することで同様の機能を実装することもできます。 Runnable インターフェイスを実装するには、その run メソッドをオーバーライドする必要があります。

以下は例です:

public class Test {
    public static void main(String[] args)  {
        System.out.println("主线程ID:"+Thread.currentThread().getId());
        MyRunnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        thread.start();
    }
}
 
 
class MyRunnable implements Runnable{
     
    public MyRunnable() {
         
    }
     
    @Override
    public void run() {
        System.out.println("子线程ID:"+Thread.currentThread().getId());
    }
}

Runnable の中国語の意味はその名前が示すように、Runnable インターフェイスを実装することでサブタスクを定義し、そのサブタスクを渡します。実行用のスレッドに。このメソッドは、Thread クラスのパラメータとして Runnable を使用し、次に Thread の start メソッドを使用してサブタスクを実行する新しいスレッドを作成する必要があることに注意してください。 Runnable の run メソッドを呼び出した場合、この通常のメソッド呼び出しでは新しいスレッドは作成されません。

実際、Thread クラスの実装ソース コードを見ると、Thread クラスが Runnable インターフェイスを実装していることがわかります。

Java では、これら 2 つのメソッドを使用してサブタスクを実行するスレッドを作成できます。どちらのメソッドを選択するかは、ユーザー自身のニーズによって異なります。 Thread クラスを直接継承することは、Runnable インターフェイスを実装するより簡単に見えるかもしれませんが、Java では単一の継承しか許可されないため、カスタム クラスが他のクラスを継承する必要がある場合、Runnable インターフェイスの実装を選択することしかできません。

3. Callable と Future を使用してスレッドを作成する

Runnable インターフェイスとは異なり、Callable インターフェイスはスレッドの実行本体として call() メソッドを提供します。 ) メソッド run() メソッドよりも強力です。

戻り値を持つスレッドを作成して開始する手順は次のとおりです。

Callable インターフェイスの実装クラスを作成し、call() メソッドを実装します。次に、インスタンスの実装クラスを作成します (java8 以降では、Lambda 式を直接使用して Callable オブジェクトを作成できます)。

  1. FutureTask クラスを使用して Callable オブジェクトをラップします。FutureTask オブジェクトは、Callable オブジェクトの call() メソッドの戻り値をカプセル化します。 ##FutureTask オブジェクトを使用する Thread オブジェクトのターゲットとしてスレッドを作成して開始します (FutureTask は Runnable インターフェイスを実装しているため)

  2. FutureTask オブジェクトの get() メソッドを呼び出して取得します子スレッドの実行終了後の戻り値

  3. 次は例です:

    public class Main {
    
      public static void main(String[] args){
    
       MyThread3 th=new MyThread3();
    
       //使用Lambda表达式创建Callable对象
    
         //使用FutureTask类来包装Callable对象
    
       FutureTask<Integer> future=new FutureTask<Integer>(
    
        (Callable<Integer>)()->{
    
          return 5;
    
        }
    
        );
    
       new Thread(task,"有返回值的线程").start();//实质上还是以Callable对象来创建并启动线程
    
        try{
    
        System.out.println("子线程的返回值:"+future.get());//get()方法会阻塞,直到子线程执行结束才返回
    
        }catch(Exception e){
    
        ex.printStackTrace();
    
       }
    
      }
    
    }

  4. スレッドを作成する 3 つの方法の比較:
  5. Runnable の実装と Callable インターフェイスの実装 これらのメソッドは基本的に同じですが、後者には call() メソッドの実行時に戻り値があり、後者には run() メソッドの実行時に戻り値がない点が異なります。したがって、この 2 つのメソッドは Thread クラスを継承するメソッドと同じです。

## という違いがあります。 #Threads は Runnable または Callable インターフェイスのみを実装し、他のクラスを継承することもできます。


この方法では、複数のスレッドがターゲット オブジェクトを共有できます。これは、複数のスレッドが同じリソースを処理する状況に非常に適しています。

    ただし、現在のスレッドにアクセスする必要がある場合、プログラミングは少し複雑です。Thread.currentThread() メソッドを呼び出す必要があります。
  1. #Thread クラスを継承するスレッド クラスは、他の親クラスから継承することはできません (Java 単一継承の決定)。
  2. PS: 一般的には、インターフェイスを実装してマルチスレッドを作成することをお勧めします

以上がJava でスレッドを作成する 3 つの方法 (コード) の紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。