Javaスレッドの理解について話す(2)--------キーワードjoin

さて、前回の記事では、スレッドの作成と操作について予備的に理解しているので、キーワード結合について話しましょう。

Javaスレッドに少し精通しているパートナーは、Synchronizedがロックを追加して、マルチスレッドがリソースをプリエンプトするのを防ぎ、データセキュリティを向上させることができることを知っています。もちろん、Synchronizedについて言及するときは、参加、待機、通知などについて考えることもできます。

最初に参加について話しましょう。この言葉は誰にでもよく知られています。つまり、;参加;参加;のメンバーになることを意味します。

プログラムを見てみましょう。

package com.example.thread;

public class MyThreadPool {

    public static void main(String[] args) throws Exception {

        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程一开始"+Thread.currentThread());
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程一结束"+Thread.currentThread());
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程二开始"+Thread.currentThread());
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程二结束"+Thread.currentThread());
            }
        });
        System.out.println("main 方法开始。。。。"+Thread.currentThread());

        thread1.start();
        thread2.start();

//        thread1.join();
//        thread2.join();
        System.out.println("main 方法结束。。。。"+Thread.currentThread());
    }

}

以下の操作の結果を見てみましょう。

main 方法开始。。。。Thread[main,5,main]
main 方法结束。。。。Thread[main,5,main]
线程一开始Thread[Thread-0,5,main]
线程二开始Thread[Thread-1,5,main]
线程一结束Thread[Thread-0,5,main]
线程二结束Thread[Thread-1,5,main]

Process finished with exit code 0

これは問題ありません。メインスレッドは2つのスレッドを追加することで開始され、マルチスレッドは相互に影響を与えることなく実行されます。スレッド1とスレッド2の開始には時間がかかるため、メインスレッドが最初に終了します。次に、スレッド1とスレッド2が開始され、5秒間の待機は明らかに終了します。

結合が追加された場合はどうなりますか?操作の結果を見てみましょう:

main 方法开始。。。。Thread[main,5,main]
线程二开始Thread[Thread-1,5,main]
线程一开始Thread[Thread-0,5,main]
线程二结束Thread[Thread-1,5,main]
线程一结束Thread[Thread-0,5,main]
main 方法结束。。。。Thread[main,5,main]

見てみましょう。メインスレッドを最初に開始してから、スレッド1とスレッド2を開始しても問題ありません。間隔が短すぎて相互に影響を与えないため、最初は最初ではない可能性があります。出力されますが、mainメソッドの前にある必要があります。最初に終了します。どうして?参加してください!スレッド1とスレッド2がjoinメソッドを呼び出すからです!

このプログラムの動作を見てみましょう。最初に、3つのスレッドが互いに影響を与えることなく開始され(joinメソッドが呼び出される前)、次にスレッド1とスレッド2の両方がjoinを呼び出します。最初に、スレッド1がjoinを呼び出し、スレッド1は挟まれています。メインスレッドは最後から始まり、スレッド2の呼び出しが再び結合し、中央にジャンプするため、スレッド2とスレッド1のメソッドが最初に終了します。

なぜですか?

join()のソースコードを見てみましょう。

 public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

コードから、私たちは見つけることができます。mills == 0の場合、while(isAlive())ループに入ります。つまり、子スレッドが生きている限り、メインスレッドは待機し続けます。

したがって、スレッド1とスレッド2は、実際にはmainメソッドのリソースをプリエンプトし、キューの先頭にジャンプすると、自然に最初に実行を終了します。

さて、今日ここに来て、明日同期を追加しましょう[笑って泣いて]

 

犠牲も勝利もありません!!!

おすすめ

転載: blog.csdn.net/zsah2011/article/details/107922351