[マルチスレッド] -Threadクラスのコンストラクターからスレッドを作成するために必要な基本要素を分析します

1つは、Threadクラスのコンストラクターです。

実際の開発では、新しいスレッドタスクを開始したい場合はどうすればよいですか?そうです、Threadクラスのstart()メソッドを呼び出して、新しいスレッドタスクを開始します。では、新しいスレッドを開始するための基本要素としてのThreadオブジェクトに必要な条件は何ですか?Threadクラスのコンストラクターで分析を開始できます。

Thread t1 =new Thread();

では、空のパラメーターコンストラクターは私たちのために何をしますか?コンストラクターをクリックして、次のコードを確認します。

	public Thread() {
    
    
		init(null, null, "Thread-" + nextThreadNum(), 0L);
	}

Threadクラスは、空のパラメーターを使用してコンストラクターでinitというメソッドを呼び出します。引き続き、initメソッドを入力して、以下を調べます。

	private void init(ThreadGroup paramThreadGroup, Runnable paramRunnable, String paramString, long paramLong) {
    
    
		init(paramThreadGroup, paramRunnable, paramString, paramLong, null, true);
	}

initメソッドでは、独自のオーバーロードされたメソッドinitを呼び出します。今日、このオーバーロードされたメソッドのパラメーターからスレッドを作成するための最も基本的な要素を分析する必要があります。もちろん、Threadクラスによって提供されるコンストラクターで言及されているパラメーターの分析に引き続き焦点を当てています。これにより、Threadクラスが生成されるときにどのパラメーターが最も重要であるかを簡単に理解できます。まず、JDKのドキュメントを開き、Threadクラスを見つけてから、JDKが提供する構築メソッドを確認します。
ここに画像の説明を挿入

1.スレッドタスク(実行可能)

まず第一に、これは私が長い間苦労したところです。JDKのドキュメントに記載されているように、スレッドを作成する2つの方法は、スレッドクラスを継承するか、実行可能なインターフェイスを実装することです。マルチスレッドビジネスを本当に実装する場合は、スレッドクラスのstart()メソッドを使用して実現する必要があります。 、および実行可能オブジェクトのrunメソッドを直接呼び出すことは、現在のスレッド処理ビジネスによって異なります。たとえば、次のコード:

package xiao.thread.constructor;

public class Demo01 implements Runnable{
    
    
	@Override
	public void run() {
    
    
		System.out.println("当前线程名是:"+Thread.currentThread().getName());
	}
	public static void main(String[] args) {
    
    
		new Demo01().run();
	}
}

newを介してランナブルインターフェイスを実装するインスタンスを作成し、runメソッドで現在使用しているスレッド名を出力します。
ここに画像の説明を挿入
インスタンスは新しいスレッドを実装していませんが、メインスレッドを使用して処理を続行していることがわかります。 runメソッド。本体のロジック。runメソッドのロジックを新しいスレッドで処理する場合は、次のように記述する必要があります。

package xiao.thread.constructor;

public class Demo01 implements Runnable{
    
    
	@Override
	public void run() {
    
    
		System.out.println("当前线程名是:"+Thread.currentThread().getName());
	}

	public static void main(String[] args) {
    
    
		new Thread(new Demo01()).start();
	}
}

この時点での結果は次のとおりです。
ここに画像の説明を挿入
この時点で、ビジネスユニットは、必要なタスクロジックを処理するための新しいスレッドを実際に開始しています。では、JDK APIドキュメントに記載されている2つの作成方法に問題はありますか?実際、これはこの文の理解に問題があるはずだと思います。上記のコードから、実行可能なインターフェイスを実装してもスレッドが開始されないことを確認するのは難しくありませんが、スレッドで実行できるタスクが提供されます。そうすれば、実行可能なインターフェイスの実装とThreadクラスの継承により、実際にスレッドタスクが作成されることがわかります。このタスク自体は開始できません。このタスクを開始する場合は、既存のタスクのみに依存できます。スレッドにすることができます。新しいスレッドを介してこのタスクを実行するには、Threadクラスのローカルメソッドstartを介してこのタスクを実行する必要があります。したがって、Threadクラスは、コンストラクター内のパラメーターを提供します。
ここに画像の説明を挿入
このパラメーター化された構造を使用して、新しいスレッドを開始し、完了したいスレッドタスクを実行できます。もちろん、匿名の内部クラスを直接使用してスレッドタスクを作成することもできます。

	public static void main(String[] args) {
    
    
		new Thread(() -> {
    
    
			System.out.println("当前线程名是:" + Thread.currentThread().getName());
		}).start();;
	}

2.スレッド名

アリババが19年に発行したプログラミング仕様では、スレッドに意味のある名前を付ける必要があることが明確に規定されています。
ここに画像の説明を挿入
理由も非常に明確であり、問​​題が再び発生したときに戻るためです。もちろん、これはアリババが提唱する仕様にすぎません。新しいラインシティを構築するときに、スレッド名を指定しないとどうなりますか?Threadクラスのinitメソッドには、次のコードが表示されます。

		init(null, null, "Thread-" + nextThreadNum(), 0L);

新しいスレッドの名前を指定しない場合、スレッドはThread-で始まり、nextThreadNumによって取得された番号をスプライスして、現在のスレッドの名前を記録します。この名前の類似性が高いため、オンラインで問題が発生した場合、間違いなくワークロードが増加します。例:
ここに画像の説明を挿入
jstackコマンドを使用してスレッドを追跡する場合、これらの参照されていないスレッド名のために、最初に問題のあるモジュールを見つけることができません。したがって、スレッドを作成するときは、トレーサビリティを容易にするために、現在のビジネス情報をスレッド名に入れるのが最善です。

3.スレッドグループ(ThreadGroup)

まず、スレッドグループの定義を確認する必要があります。

スレッドグループ(ThreadGroup)は、スレッドで構成されるスレッド管理クラスです
。Javaでは、各スレッドはスレッドグループ管理のメンバーに属します。たとえば、スレッドはメイン関数main()のメインワークフローで生成されます。スレッドは、メインスレッドグループ管理のメンバーに属しています。

スレッドグループは理解しやすく、スレッドの管理に使用されます。スレッドグループ間の関係は、中国の家族経営と非常によく似ています。誰もがスレッドを持っており、決して自由になることはできません。また、スレッドは自分が属するスレッドグループを見つけることもできます。スレッドグループは日常業務ではあまり使用されません。主に割り込み/一時停止/再開/停止などのスレッドのバッチを管理するために使用されます。ここではThreadGroupの破棄に注意してください。方法はこのスレッドをクリアすることです。 groupとそのすべての子スレッドグループ。ただし、子スレッドグループを含むここでのすべてのスレッドグループは空でなければならないことに注意してください。つまり、スレッドグループ内のすべてのスレッドが停止しています。そうでない場合、例外がスローされます。
添付ファイル:スレッドグループの管理方法

1)自動帰属、つまりスレッドまたはスレッドグループにはデフォルトのメカニズムがあります。素人の用語では、スレッドまたはスレッドグループを作成するには、独自のスレッドグループが必要であり、各スレッドを解放することはできません。これは、表示することで実行できます。 new Thread()とnew ThreadGroup()のソースコードがわかります。
2)スレッドグループはツリー構造で実装されているため、親オブジェクトは子オブジェクトを作成できますが、子オブジェクトは引き続き子オブジェクトを作成できます。

4.スタックサイズ(stackSize)

ここに画像の説明を挿入
Threadの最後のコンストラクターとして、stackSizeは主に、新しく作成されたスレッドのスタックスペースのサイズを指定するために使用されます。このサイズは、ソースコードのデフォルト値も指定します。
ここに画像の説明を挿入
では、なぜ0にする必要があるのでしょうか。
stackSizeパラメーターが有効になるかどうかは、jvmが実行されているプラ​​ットフォームに依存するため、この問題はJVMドキュメントで明確に説明されています。プラットフォームがstackSizeパラメーターをサポートしてスタックスペースサイズを指定する場合、jvmはによってサポートされる最小値を使用します。プラットフォーム。スタックスペースサイズを初期化します。したがって、パラメータ0は、プラットフォームでサポートされる最小スタックメモリサイズが作成されることを意味します。

ここに画像の説明を挿入

2、まとめ

Threadクラスのコンストラクターの分析を通じて、スレッドを作成するときに主に次の4つの要素が必要であることが主にわかります。

  1. runnableによって提供されるスレッドタスク:ここでは
    ここに画像の説明を挿入
    、ビジネスの分離または拡張のみを実現したい場合に、JDK APIドキュメント記載されていることに注意する必要があります。拡張または統合を希望しない限り、スレッドを統合しないことをお勧めします。 Threadの機能。それ以外の場合は、実行可能なインターフェイスを実装するために使用する必要があります。
  2. スレッド名スレッドのビジネスに適した名前を確立すると、後で問題をトラブルシューティングするときに多くの時間を節約できます。
  3. スレッドグループ:特定のスレッドグループを指定すると、特定のビジネススレッドをすばやく維持するのに便利です。
  4. スレッドサイズ:指定されたサイズのスレッドを作成すると、スタックメモリスペースの使用率を計算するのも容易になります

おすすめ

転載: blog.csdn.net/xiaoai1994/article/details/109801909