1. クラス変数とメソッドを通じてデータを返す
このメソッドを使用してデータを返すには、クラス変数またはメソッドを通じてデータを取得する前に start メソッドを呼び出す必要があります。まず例 2-13 からどのような結果が得られるかを見てみましょう。
次のようにコードをコピーします。
パッケージの mythread;
パブリッククラスMyThreadはThreadを拡張します
{
プライベート文字列値1;
プライベート文字列値2;
public void run()
{
value1 = "メンバー変数を通じてデータを返す";
value2 = "メンバーメソッドを通じてデータを返す";
}
public static void main(String[] args) が例外をスローする
{
MyThread スレッド = new MyThread();
thread.start();
System.out.println("value1:" + thread.value1);
System.out.println("value2:" + thread.value2);
}
}
上記のコードを実行すると、次の結果が出力される場合があります。
次のようにコードをコピーします。
値1:null
値2:null
上記の実行結果は非常に異常に見えます。 runメソッドでvalue1とvalue2に値が代入されていますが、nullが返されます。なぜこのようなことが起こるかというと、start メソッドを呼び出した直後に value1 と value2 の値が出力されており、ここでの run メソッドはまだ value1 と value2 に値を代入するステートメントを実行していないためです。この状況を回避するには、value1 と value2 を出力するコードを実行する前に、run メソッドが実行されるまで待つ必要があります。したがって、sleep メソッドを使用してメインスレッドを遅延させることを考えることができます。たとえば、thread.start() の後に次のステートメントを追加できます。
睡眠(1000);
これを行うと、続行する前にメインスレッドを 1 秒遅延させることができますが、これには問題があります。それは、どのくらい遅延させるかをどうやって知るかということです。この例では、run メソッドに代入ステートメントが 2 つしかなく、スレッドも 1 つだけ作成されるため、1 秒の遅延で十分ですが、run メソッド内のステートメントが複雑な場合、この時間を予測するのは困難です。したがって、この方法は安定していません。
ここでの目的は value1 と value2 の値を取得することなので、value1 と value2 が null かどうかを判断するだけで済みます。どちらもnullでない場合は、この2つの値を出力できます。この目的を達成するには、次のコードを使用できます。
次のようにコードをコピーします。
while (thread.value1 == null || thread.value2 == null);
上記のステートメントを使用すると、この状況を非常に安定して回避できますが、この方法はシステム リソースを大量に消費します。 run メソッドのコードが非常に複雑な場合、value1 と value2 の割り当てに長い時間がかかることが想像できます。そのため、value1 と value2 の両方が空でなくなるまで while ループを実行し続ける必要があります。したがって、上記のステートメントに次のような改善を加えることができます。
次のようにコードをコピーします。
while (thread.value1 == null || thread.value2 == null)
睡眠(100);
whileループでは、初めてvalue1とvalue2の値を判定した後、100ミリ秒スリープしてから、これら2つの値を判定します。これにより、占有されるシステム リソースが少なくなります。
上記の方法は非常にうまく解決できますが、Java のスレッド モデルは、join メソッドというより良い解決策を提供します。前に説明したように、結合の機能は、スレッドを使用して非同期実行から同期実行に変更することです。スレッドが同期実行されると、通常のメソッドから戻りデータを取得するのと何ら変わりません。したがって、この問題は、次のようなコードを使用してより効率的に解決できます。
次のようにコードをコピーします。
thread.start();
thread.join();
thread.join() の実行後、スレッド thread の run メソッドが終了します。これは、スレッド thread が終了したことを意味します。したがって、thread.join() の後に MyThread クラスの任意のリソースを安全に使用して、返されたデータを取得できます。
2. コールバック関数を通じてデータを返す
実際、この方法は「スレッドにデータを渡す 3 つの方法」で紹介されています。記事「スレッドにデータを渡す3つの方法」の例では、計算結果はWorkクラスのprocessメソッドを通じてスレッドに渡されますが、同時にスレッドから3つの乱数も取得します。処理方法。したがって、このメソッドはスレッドにデータを渡したり、スレッドからデータを取得したりすることができます。