検索
ホームページJava&#&チュートリアルJavaでマルチスレッドを実装するにはどのような方法がありますか?

はじめに

Java マルチスレッドを実装するには、主に 4 つの方法があります。

① Thread クラスを継承し、Runnable インターフェイスを実装します。

② Callable インターフェイスを実装し、 FutureTask ラッパー Thread スレッドを通じて作成します。

③ ExecutorService と Callable を使用します。

④ Future で結果を返すマルチスレッドを実装します。

最初の 2 つのメソッドには、その後の戻り値がありません。スレッドが実行され、後の 2 つのメソッドの種類には戻り値があります。

1. マルチスレッドを実装する 4 つの方法

1. Thread クラスを継承してスレッドを作成する

Thread クラスは、本質的には Runnable インターフェイスを実装するインスタンスであり、スレッドの例。 Thread クラスの start() インスタンス メソッドを使用することが、スレッドを開始する唯一の方法です。 run() メソッドを実行する新しいスレッドは、ネイティブ メソッドである start() メソッドを呼び出すことによって開始されます。この方法でマルチスレッドを実装するのは非常に簡単で、独自のクラスを通じて Thread を直接拡張し、run() メソッドをオーバーライドすることで、新しいスレッドを開始し、独自に定義した run() メソッドを実行できます。例:

public class MyThread extends Thread {  
  public void run() {  
   System.out.println("MyThread.run()");  
  }  
}  
MyThread myThread1 = new MyThread();  
MyThread myThread2 = new MyThread();  
myThread1.start();  
myThread2.start();

2. Runnable インターフェイスを実装してスレッドを作成する

クラスが別のクラスを拡張している場合、Thread を直接拡張することはできません。この時点で、Runnable インターフェイスを実装できます。

public class MyThread extends OtherClass implements Runnable {  
  public void run() {  
   System.out.println("MyThread.run()");  
  }  
}

MyThread を開始するには、最初に Thread をインスタンス化し、独自の MyThread インスタンスを渡す必要があります:

MyThread myThread = new MyThread();  
Thread thread = new Thread(myThread);  
thread.start();

実際には、Runnable ターゲット パラメータが に渡されるとき、 Thread、Thread の run() メソッドは target.run() を呼び出し、JDK ソース コードを参照します:

public void run() {  
  if (target != null) {  
   target.run();  
  }  
}

3. Callable インターフェイスの実装

FutureTask ラッパーを通じて Thread スレッドを作成します

Callable インターフェイス (メソッドは 1 つだけです) は次のように定義されています:

public interface Callable<V>   { 
  V call() throws Exception;   } 
public class SomeCallable<V> extends OtherClass implements Callable<V> {
    @Override
    public V call() throws Exception {
        // TODO Auto-generated method stub
        return null;
    }
}
Callable<V> oneCallable = new SomeCallable<V>();   
//由Callable<Integer>创建一个FutureTask<Integer>对象:   
FutureTask<V> oneTask = new FutureTask<V>(oneCallable);   
//注释:FutureTask<Integer>是一个包装器,它通过接受Callable<Integer>来创建,它同时实现了Future和Runnable接口。 
  //由FutureTask<Integer>创建一个Thread对象:   
Thread oneThread = new Thread(oneTask);   
oneThread.start();   //至此,一个线程就创建完成了。

4. 結果を返すスレッドを実装します

ExecutorService、Callable、および Future を使用して、結果を返すスレッド

ExecutorService。Callable と Future の 3 つのインターフェイスは、実際には Executor フレームワークに属します。 JDK1.5では、結果を返すスレッドが新機能として導入され、戻り値を取得する手間がなくなりました。また、たとえ自分で実装したとしても、抜け穴がたくさんある可能性があります。

値を返すことができるタスクは、Callable インターフェイスを実装する必要があります。同様に、値を返さないタスクは Runnable インターフェイスを実装する必要があります。

Callable タスクの実行後、Future オブジェクトを取得できます。そのオブジェクトに対して get を呼び出すことで、Callable タスクから返される Object を取得できます。

注: get メソッドはブロックされています。つまり、スレッドは結果を返さず、get メソッドは永久に待機します。

スレッド プール インターフェイス ExecutorService と組み合わせると、結果が返される伝説的なマルチスレッドを実現できます。

JDK1.5 で検証されており問題ありません。以下に示す結果が返されるマルチスレッド テスト サンプルを直接使用できます。コードは次のとおりです:

import java.util.concurrent.*;  
import java.util.Date;  
import java.util.List;  
import java.util.ArrayList;  
/** 
* 有返回值的线程 
*/  
@SuppressWarnings("unchecked")  
public class Test {  
public static void main(String[] args) throws ExecutionException,  
    InterruptedException {  
   System.out.println("----程序开始运行----");  
   Date date1 = new Date();  
   int taskSize = 5;  
   // 创建一个线程池  
   ExecutorService pool = Executors.newFixedThreadPool(taskSize);  
   // 创建多个有返回值的任务  
   List<Future> list = new ArrayList<Future>();  
   for (int i = 0; i < taskSize; i++) {  
    Callable c = new MyCallable(i + " ");  
    // 执行任务并获取Future对象  
    Future f = pool.submit(c);  
    // System.out.println(">>>" + f.get().toString());  
    list.add(f);  
   }  
   // 关闭线程池  
   pool.shutdown();  
   // 获取所有并发任务的运行结果  
   for (Future f : list) {  
    // 从Future对象上获取任务的返回值,并输出到控制台  
    System.out.println(">>>" + f.get().toString());  
   }  
   Date date2 = new Date();  
   System.out.println("----程序结束运行----,程序运行时间【"  
     + (date2.getTime() - date1.getTime()) + "毫秒】");  
}  
}  
class MyCallable implements Callable<Object> {  
private String taskNum;  
MyCallable(String taskNum) {  
   this.taskNum = taskNum;  
}  
public Object call() throws Exception {  
   System.out.println(">>>" + taskNum + "任务启动");  
   Date dateTmp1 = new Date();  
   Thread.sleep(1000);  
   Date dateTmp2 = new Date();  
   long time = dateTmp2.getTime() - dateTmp1.getTime();  
   System.out.println(">>>" + taskNum + "任务终止");  
   return taskNum + "任务返回运行结果,当前任务时间【" + time + "毫秒】";  
}  
}

2. マルチスレッド関連の知識

1. Runnable と Callable の違い

主な違いは、 Runnable インターフェイスには戻り値がありません。

Callable インターフェイスの call メソッドには戻り値があり、汎用の Runnable インターフェイスをサポートしています。run メソッドはランタイム例外をスローすることのみが可能であり、キャプチャして処理することはできません。

Callable インターフェイスの call メソッドを使用すると、例外をスローし、例外情報を取得できます

2. 新しいスレッドの開始方法と、start メソッドと run メソッドの呼び出しの違い

スレッド オブジェクトは、スレッドを開始せずに run メソッドを呼び出します。オブジェクトのみがメソッドを呼び出します。

スレッド オブジェクトは、start を呼び出してスレッドを開き、jvm に run メソッドを呼び出して、開いたスレッドで実行させます。start メソッドを呼び出すと、スレッドが開始され、スレッドが準備完了状態になります。 run メソッドはスレッドの通常のメソッド、またはメインスレッドで実行されます。

3. スレッドに関連する基本メソッド

スレッドに関連する基本メソッドには、wait、notify、notifyAll、sleep、join、yield などが含まれます。

Thread wait (wait) ) これを呼び出します メソッドのスレッドは待機状態に入り、別のスレッドからの通知を待つか中断された場合にのみ戻ります。wait() メソッドを呼び出した後、オブジェクトのロックが解放されることに注意してください。したがって、wait メソッドは通常、同期メソッドまたは同期コード ブロックで使用されます。

スレッド スリープ (スリープ) sleep は現在のスレッドをスリープさせます。wait メソッドとは異なり、sleep は現在占有されているロックを解放しません。sleep(long) はスレッドを TIMED-WATING 状態にします。 wait() メソッドは、現在のスレッドを待機状態にします。

スレッド イールド (yield) イールドは、現在のスレッドに CPU 実行タイム スライスを譲り渡し、CPU をめぐって他のスレッドと再競合させます。タイムスライス。一般に、優先度の高いスレッドは CPU タイム スライスの競合に成功する可能性が高くなりますが、これは絶対的なものではなく、一部のオペレーティング システムはスレッドの優先度に敏感ではありません。

スレッド割り込み (割り込み) スレッドの割り込みは、スレッドに通知信号を与えることを目的としており、これはスレッド内の割り込みフラグに影響します。このため、このスレッド自体は状態 (ブロック、終了など) を変更しません。

Join は、他のスレッドが join() メソッドを終了するのを待ち、他のスレッドが終了するのを待って、現在のスレッドのスレッドの join() メソッドが実行されると、現在のスレッドはブロッキング状態に変化し、別のスレッドに戻って終了します。現在のスレッドは再びブロッキング状態から準備完了状態に変化し、スレッドの好意を待ちます。 CPU。###

スレッドウェイクアップ (通知) Object クラスの Notice() メソッドは、このオブジェクト モニターで待機している単一のスレッドをウェイクアップします。すべてのスレッドがこのオブジェクトで待機している場合、スレッドの 1 つがウェイクアップするために選択されます。この選択は任意であり、実装の決定が行われたときに発生し、スレッドは、現在のスレッドがこのオブジェクトのロックを放棄するまで、ウェイクアップされたスレッドの実行を続行できるようになるまで、wait() メソッドの 1 つを呼び出してオブジェクトのモニター上で待機します。目覚めたスレッドは、オブジェクト上でアクティブに同期している他のすべてのスレッドと通常の方法で競合します。もう 1 つの同様のメソッドは、同じモニター上で待機しているすべてのスレッドを起動する、notifyAll() です。

4. wait() と sleep() の違い

① 異なるクラスから wait(): Object クラスから; sleep(): Thread クラスから;

② ロックの解放について wait(): 待機処理中にロックを解放する; sleep(): 待機中にロックを解放しない

③ 使用範囲: wait():同期する必要がある コードブロック内で使用; sleep(): どこでも使用可能;

④ 例外をキャッチするかどうか wait(): 例外をキャッチする必要がない; sleep(): 例外をキャッチする必要がある;

5 .マルチスレッドの原則

マルチスレッドの原則: マルチスレッドは並行して実行されます。 CPU の場合、ある時点で 1 つのプログラム、つまり同時に 1 つのプロセスしか実行できず、CPU はこれらのプロセスを継続的に切り替え、各スレッドは 1 回ずつ実行されます。 CPU の実行速度が人間の感覚に比べて速すぎるため、CPU は複数のプロセスをローテーションして実行しますが、あたかも複数のプロセスが同時に実行されているように感じられます。

CPU は複数のプロセスを切り替えますが、プログラムを開きすぎると、CPU が各プロセスに切り替えるまでの時間も長くなり、マシンの動作が遅くなったように感じられます。マルチスレッドを合理的に使用すると効率が向上しますが、過度に使用しても効率は向上しません。

マルチスレッド技術は、主にプロセッサ ユニットでのマルチスレッド実行の問題を解決し、プロセッサ ユニットのアイドル時間を大幅に短縮し、プロセッサ ユニットのスループット能力を向上させることができます。

Javaでマルチスレッドを実装するにはどのような方法がありますか?

以上がJavaでマルチスレッドを実装するにはどのような方法がありますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事は亿速云で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
高度なJavaプロジェクト管理、自動化の構築、依存関係の解像度にMavenまたはGradleを使用するにはどうすればよいですか?高度なJavaプロジェクト管理、自動化の構築、依存関係の解像度にMavenまたはGradleを使用するにはどうすればよいですか?Mar 17, 2025 pm 05:46 PM

この記事では、Javaプロジェクト管理、自動化の構築、依存関係の解像度にMavenとGradleを使用して、アプローチと最適化戦略を比較して説明します。

適切なバージョン化と依存関係管理を備えたカスタムJavaライブラリ(JARファイル)を作成および使用するにはどうすればよいですか?適切なバージョン化と依存関係管理を備えたカスタムJavaライブラリ(JARファイル)を作成および使用するにはどうすればよいですか?Mar 17, 2025 pm 05:45 PM

この記事では、MavenやGradleなどのツールを使用して、適切なバージョン化と依存関係管理を使用して、カスタムJavaライブラリ(JARファイル)の作成と使用について説明します。

カフェインやグアバキャッシュなどのライブラリを使用して、Javaアプリケーションにマルチレベルキャッシュを実装するにはどうすればよいですか?カフェインやグアバキャッシュなどのライブラリを使用して、Javaアプリケーションにマルチレベルキャッシュを実装するにはどうすればよいですか?Mar 17, 2025 pm 05:44 PM

この記事では、カフェインとグアバキャッシュを使用してJavaでマルチレベルキャッシュを実装してアプリケーションのパフォーマンスを向上させています。セットアップ、統合、パフォーマンスの利点をカバーし、構成と立ち退きポリシー管理Best Pra

キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPA(Java Persistence API)を使用するにはどうすればよいですか?キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPA(Java Persistence API)を使用するにはどうすればよいですか?Mar 17, 2025 pm 05:43 PM

この記事では、キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPAを使用することについて説明します。潜在的な落とし穴を強調しながら、パフォーマンスを最適化するためのセットアップ、エンティティマッピング、およびベストプラクティスをカバーしています。[159文字]

Javaのクラスロードメカニズムは、さまざまなクラスローダーやその委任モデルを含むどのように機能しますか?Javaのクラスロードメカニズムは、さまざまなクラスローダーやその委任モデルを含むどのように機能しますか?Mar 17, 2025 pm 05:35 PM

Javaのクラスロードには、ブートストラップ、拡張機能、およびアプリケーションクラスローダーを備えた階層システムを使用して、クラスの読み込み、リンク、および初期化が含まれます。親の委任モデルは、コアクラスが最初にロードされ、カスタムクラスのLOAに影響を与えることを保証します

分散コンピューティングにJavaのRMI(リモートメソッドの呼び出し)を使用するにはどうすればよいですか?分散コンピューティングにJavaのRMI(リモートメソッドの呼び出し)を使用するにはどうすればよいですか?Mar 11, 2025 pm 05:53 PM

この記事では、分散アプリケーションを構築するためのJavaのリモートメソッドの呼び出し(RMI)について説明します。 インターフェイスの定義、実装、レジストリのセットアップ、およびクライアント側の呼び出しを詳述し、ネットワークの問題やセキュリティなどの課題に対処します。

ネットワーク通信にJavaのソケットAPIを使用するにはどうすればよいですか?ネットワーク通信にJavaのソケットAPIを使用するにはどうすればよいですか?Mar 11, 2025 pm 05:53 PM

この記事では、ネットワーク通信のためのJavaのソケットAPI、クライアントサーバーのセットアップ、データ処理、リソース管理、エラー処理、セキュリティなどの重要な考慮事項をカバーしています。 また、パフォーマンスの最適化手法も調査します

Javaでカスタムネットワークプロトコルを作成するにはどうすればよいですか?Javaでカスタムネットワークプロトコルを作成するにはどうすればよいですか?Mar 11, 2025 pm 05:52 PM

この記事では、カスタムJavaネットワーキングプロトコルの作成を詳述しています。 プロトコルの定義(データ構造、フレーミング、エラー処理、バージョン化)、実装(ソケットを使用)、データシリアル化、およびベストプラクティス(効率、セキュリティ、メンテナ

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。