目次
メソッド 3 の作成プロセス:
总结
常用方法
Thread获取和设置线程名称
Thread类的线程休眠方法
ホームページ Java &#&チュートリアル Javaのスレッドを理解する方法

Javaのスレッドを理解する方法

Apr 29, 2023 pm 10:01 PM
java

Javaのスレッドを理解する方法

スレッドはプログラム内の実行パスです。私たちがよく知っている主なメソッドは、実際には単一の実行パスです。プログラム内に実行パスが 1 つしかない場合、プログラムは次のようになります。単一の実行パス スレッド化されたプログラム; スレッドが 1 つであるため、マルチスレッドも存在します 文字通りの意味は、「単一のスレッドに対するソフトウェアおよびハードウェア上の複数の実行プロセスのテクノロジ」と理解できます。マルチスレッドの利点は、 CPU レートの使用率を向上させることです。マルチスレッド プログラムでは、1 つのスレッドが待機する必要がある場合、CPU は待機する代わりに他のスレッドを実行できるため、プログラムの効率が大幅に向上します。

マルチスレッドの作成

方法 1: Thread クラスを継承

方法 1 の作成プロセス:

  • サブクラスを定義するMyThread スレッド クラス java.lang.Thread を継承し、run() メソッドをオーバーライドします。

  • MyThread クラスのオブジェクトを作成します。

  • スレッド オブジェクトを呼び出す start() メソッドはスレッドを開始します (run() メソッドは起動後も実行されます);

    public class ThreadDemo01 {
        public static void main(String[] args) {
            MyThread myThread1 = new MyThread();
            myThread1.start();
            for (int i = 0; i < 3; i++) {
                System.out.println("主线程正在执行~~");
            }
        }
    }
    class MyThread extends Thread{
        @Override
        public void run() {
            for (int i = 0; i < 3; i++) {
                System.out.println("子线程正在执行~~");
            }
    
        }
    }
    //输出结果(不唯一):
    //主线程正在执行~~
    //主线程正在执行~~
    //主线程正在执行~~
    //子线程正在执行~~
    //子线程正在执行~~
    //子线程正在执行~~
    ログイン後にコピー

  • 上記のコードでは 2 つのスレッドが実行されています。メインスレッドとメインメソッドのスレッド 子スレッドは、オブジェクト mythread で start() を呼び出すことによって開始されました。しかし、なぜ出力結果が一意ではないのでしょうか?その理由は、実行中に 2 つのスレッド間で CPU プリエンプションが発生し、最初にそれを獲得した方が最初に実行されるためです。

それでは、スレッド オブジェクトを直接使用して run() メソッドを呼び出してみてはいかがでしょうか? run() が直接呼び出された場合、それは単なる通常の呼び出しメソッド、つまりシングルスレッドですが、start() メソッドは子スレッドの開始に使用されるため、マルチスレッドが発生する可能性があります。

方法 1 の長所と短所:

  • 長所: コーディングが簡単;

  • 短所: スレッド クラスは Thread と継承できません 他のクラスは拡張に役立ちません;

方法 2: Runnable インターフェイスの実装

方法 2 作成プロセス:

1. 定義します。スレッド タスク クラス MyRunnable Runnable インターフェイスを実装し、run() メソッドをオーバーライドします;

2. MyRunnable オブジェクトを作成します;

3. MyRunnable タスク オブジェクトを処理のために Thread に渡します;

4. スレッドを呼び出す オブジェクトの start() メソッドがスレッドを開始します;

#スレッド コンストラクターpublic Thread (文字列名)##public Thread (実行可能なターゲット) Runnable オブジェクトをカプセル化してスレッド オブジェクトにしますpublic Thread (Runnable target, String name)Runnable オブジェクトをスレッド オブジェクトとしてカプセル化し、スレッド名を指定します
public class ThreadDemo02 {
    public static void main(String[] args) {
        MyRunnable target = new MyRunnable();
        Thread thread = new Thread(target);
        thread.start();
        for (int i = 0; i < 3; i++) {
            System.out.println("主线程正在执行~~");
        }
    }
}
class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            System.out.println("子线程正在执行~~");
        }

    }
}
//输出结果(不唯一):
//主线程正在执行~~
//子线程正在执行~~
//子线程正在执行~~
//子线程正在执行~~
//主线程正在执行~~
//主线程正在执行~~
ログイン後にコピー
このコード 最初の方法との違いは、MyRunnable タスク オブジェクトを Thread にカプセル化する必要があり、他の場所は基本的に変更されていないことです。
メソッド
現在のスレッドの名前を指定できます
方法 2 の長所と短所:

長所: スレッド タスク クラスはインターフェイスのみを実装し、引き続きクラスを継承してインターフェイスを実装できるため、拡張性が高くなります。

欠点: プログラミング オブジェクトのパッケージ化にもう 1 つの層があり、スレッドに実行結果がある場合、それを直接返すことができません。

次に、Runnable インターフェイス (匿名内部クラス フォーム) を使用してマルチスレッドの作成を実現します:

1. Runnable 匿名内部クラス オブジェクトを作成します;

2. 処理は Thread に任せます;

3. スレッド オブジェクトの start() を呼び出してスレッドを開始します;

//正常版:
public class ThreadDemo01 {
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 3; i++) {
                    System.out.println("子线程正在执行~~");
                }
            }
        });
        thread.start();
        for (int i = 0; i < 3; i++) {
            System.out.println("主线程正在执行~~");
        }
    }
}

//lambda简化版:
new Thread(()-> {
                for (int i = 0; i < 3; i++) {
                    System.out.println("子线程正在执行~~");
                }
        }).start();
ログイン後にコピー

本質的には、このメソッドには大きな違いはありません。オブジェクトは作成する必要がある単なるスレッドですが、もう 1 つは匿名の内部クラスを通じてマルチスレッドです。また、このコード ブロックはラムダ式によって効率化することもできます。この知識ポイントにまだ感銘を受けているでしょうか?忘れた場合は、次の記事を参照してください: Java でラムダ式を理解する方法 - 合理化された

方法 3: Callable インターフェイスを実装する

マルチスレッドを作成する前の 2 つの方法を学習した後、 1. 書き換えられた run() メソッドは結果を直接返すことができない; 2. スレッドの実行結果を返す必要があるビジネス シナリオには適していない。したがって、これらの問題を解決するには 3 番目の方法が必要です。

メソッド 3 の作成プロセス:

1. Callable インターフェイスを実装するクラスを定義し、call() メソッドをオーバーライドし、実行する必要があることをカプセル化します。 2. FutureTask を使用して Callable を変換します オブジェクトはスレッド タスク オブジェクトにカプセル化されます;

3. スレッド タスク オブジェクトを処理のために Thread に渡します;

4. の start() メソッドを呼び出しますスレッドを起動してタスクを実行するスレッド;

5. スレッドの実行完了後、FutureTask の get() メソッドでタスクの実行結果を取得します。

メソッド名

#説明

##public FutureTask<>(呼び出し可能呼び出し)public V get() throws Exception
public class ThreadDemo03 {
    public static void main(String[] args) throws Exception {
        MyCallable myCallable = new MyCallable();
        FutureTask<String> futureTask = new FutureTask<>(myCallable);
        Thread thread = new Thread(futureTask);
        thread.start();
        int sum= 0;
        for (int i = 0; i < 3; i++) {
            sum+=i;
        }
        System.out.println(sum);
        String s =futureTask.get();
        System.out.println(s);
    }
}
class MyCallable implements Callable<String > {
    @Override
    public String call(){
        int sum=0;
        for (int i = 0; i < 3; i++) {
            sum+=i;
        }
        return "子线程计算结果:"+sum;
    }
}
//输出结果:
//3
//子线程计算结果:3
ログイン後にコピー

方式三优缺点:

优点:

线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强;

可以在线程执行完毕后去获取 线程执行的结果;

缺点:

编码复杂一点;

总结

Encapsulate Callable オブジェクトを FutureTask オブジェクトに変換します
呼び出しメソッドを実行するスレッドによって返された結果を取得します
方式优点缺点
继承Thread类编程比较简单,可以直接使用Thread类中的方法扩展性较差,不能再继承其他的类,不能返回线程执行的结果
实现Runnable接口扩展性强,实现该接口的同时还可以继承其他的类编程相对复杂,不能返回线程执行的结果
实现Callable接口扩展性强,实现该接口的同时还可以继承其他的类,可以得到线程的执行结果编程相对复杂

常用方法

Thread获取和设置线程名称

方法名称说明
String getName()获取当前线程的名称,默认线程名称是Thread-索引
void setName(String name)

将此线程更改为指定的名称,通过构造器也可以设置线程名称

简单地通过一段代码让大家能够清晰地了解这个代码该如何使用:

public class ThreadDemo04 {
    public static void main(String[] args) throws Exception {
        thread thread1 = new thread();
        thread1.setName("1号子线程");
        thread1.start();
        thread thread2 = new thread();
        thread2.setName("2号子线程");
        thread2.start();
    }
}
class thread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            System.out.println(this.getName()+"正在执行任务"+i);
        }
    }
}
//输出结果:
//2号子线程正在执行任务0
//1号子线程正在执行任务0
//2号子线程正在执行任务1
//1号子线程正在执行任务1
//2号子线程正在执行任务2
//1号子线程正在执行任务2
ログイン後にコピー

Thread类的线程休眠方法

方法名称说明
public static void sleep(long time)让当前线程休眠指定的时间后再继续执行,单位为毫秒
public class ThreadDemo05 {
    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 5; i++) {
            System.out.println(i);
            if (i==3){
                Thread.sleep(5000);
            }
        }
    }
}
//输出结果:
//1
//2
//3
//在输出过3以后,等待5秒之后再进行输出
//4
ログイン後にコピー

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

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホット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ヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Javaの平方根 Javaの平方根 Aug 30, 2024 pm 04:26 PM

Java の平方根のガイド。ここでは、Java で平方根がどのように機能するかを、例とそのコード実装をそれぞれ示して説明します。

Javaの完全数 Javaの完全数 Aug 30, 2024 pm 04:28 PM

Java における完全数のガイド。ここでは、定義、Java で完全数を確認する方法、コード実装の例について説明します。

Java の乱数ジェネレーター Java の乱数ジェネレーター Aug 30, 2024 pm 04:27 PM

Java の乱数ジェネレーターのガイド。ここでは、Java の関数について例を挙げて説明し、2 つの異なるジェネレーターについて例を挙げて説明します。

ジャワのウェカ ジャワのウェカ Aug 30, 2024 pm 04:28 PM

Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

Javaのアームストロング数 Javaのアームストロング数 Aug 30, 2024 pm 04:26 PM

Java のアームストロング番号に関するガイド。ここでは、Java でのアームストロング数の概要とコードの一部について説明します。

Javaのスミス番号 Javaのスミス番号 Aug 30, 2024 pm 04:28 PM

Java のスミス番号のガイド。ここでは定義、Java でスミス番号を確認する方法について説明します。コード実装の例。

Java Springのインタビューの質問 Java Springのインタビューの質問 Aug 30, 2024 pm 04:29 PM

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8 Stream Foreachから休憩または戻ってきますか? Java 8 Stream Foreachから休憩または戻ってきますか? Feb 07, 2025 pm 12:09 PM

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

See all articles