8

私は実際に、スレッドがどこで実行されているかに関係なく、スレッドを強制終了するためのより簡単な方法を探しています。しかし、インターネットのほとんどのソリューションでは、ブールフラグを使用してスレッドの実行を制御するように指示されています。スレッドを停止する場合は、ブール変数をfalseに設定します。

しかし、ランナブル内のタスクがLONG線形タスクである場合、つまりタスクが繰り返されていない場合はどうなるでしょうか。その場合、タスクのブロック全体をカバーする「while」ループを作成するのはそれほど簡単ではありません。

Thread.stopを使用するのは本当に魅力的ですが、「非推奨」という警告を使用するのは非常に危険なようです。この記事を読みました 。なぜThread.stop、Thread.suspend、Thread.resume、Runtime.runFinalizersOnExitが非推奨になるのですか?

でも分かりません

これらのモニターによって以前に保護されていたオブジェクトのいずれかが不整合な状態にあった場合、他のスレッドがこれらのオブジェクトを不整合な状態で表示する可能性があります。そのような物体は損傷していると言われています。

「一貫性のない状態」とはどういう意味ですか?誰かがこれについて説明できれば幸いです。

質問をより低いレベルのビューに拡張したいと思います。たとえばi = i + 1;、JVM(おそらくアセンブリ言語も同様)では、このJavaステートメントはいくつかの小さな命令に分割されます。たとえばmove i ; add i ; get i into memory 0x0101(これは例です!私はまったくありません)アセンブリ言語を知っている!)

さて、thread.stopを呼び出すと、実際にはどこで停止しますか?スレッドはCOMPLETEDJavaステートメントの後で停止しますか、それとも「アセンブル言語」の途中にある可能性がありますか?答えが2番目の場合、それは私たちが言った理由である可能性があります

そのような物体は損傷していると言われています。

わかりました、私の質問はちょっと混乱しています。誰かが理解して説明できることを願っています。前もって感謝します。

4

5 に答える 5

5

「破損したオブジェクト」は高レベルの概念であり、JVMレベルでは発生しません。プログラマーは、クリティカルセクションをロックで保護することにより、スレッドセーフを念頭に置いてクラスを設計します。各クリティカルセクションが完全に実行されるか、まったく実行されないことは、彼のクラスの不変条件です。スレッドをstop作成すると、クリティカルセクションが途中で中断された可能性があるため、不変条件が中断されます。その瞬間、オブジェクトは損傷しています。

スレッドを停止すると、クリーンアップが実行されなかったり、取得したリソースが解放されなかったりするなど、さらに多くの危険が隠されます。スレッドが実行中の処理を放棄しない場合、アプリケーション全体を危険にさらすことなくスレッドを停止させる方法はありません。

実際には、強制的に中止する必要がある可能性のあるエイリアンコードを実行する必要がある場合は、プロセスを強制終了すると少なくともOSレベルのクリーンアップが実行され、損傷を封じ込めるのにはるかに優れているため、これは別のプロセスで実行する必要があります。

于 2012-10-31T08:53:41.867 に答える
3

「一貫性のない状態」とは、アプリケーションが気にするデータの状態、アプリケーションをロック/モニターなどでスレッドセーフにすることによってアプリケーションロジックが慎重に生成されたことを意味します。

この簡単な方法があると想像してください。

public synchronized void doSomething() 
{
      count++;
      average = count/total;
}

複数のスレッドがこのオブジェクトを使用しているため、このメソッドは他のメソッドとともに同期されます。おそらくあります

public synchronized AverageAndCount getMeasurement() 
{
   return new AverageAndCount(average, count);
}

これにより、スレッドが不完全な測定値を読み取れないことが保証されます。つまり、現在の測定値がdoSomething()などの内部で計算されている場合、getMeasurement()はそれが完了するまでブロック/待機します。

ここで、doSomethingがスレッドで実行され、.stop()そのスレッドを呼び出すと想像してください。

そのため、スレッドが実行された直後にスレッドが停止し count++;、保持されているモニターのロックが解除され、メソッドが終了してaverage = count/total;実行されない可能性があります。

これは、データに一貫性がないことを意味します。後でgetMeasurement()を呼び出すと、一貫性のないデータが取得されるようになります。

また、この時点では、これがJavaステートメントレベルで発生するのか、それより低いレベルで発生するのかはあまり関係がないことにも注意してください。データは、どのような場合でも推論できない一貫性のない状態になる可能性があります。

于 2012-10-31T09:05:07.613 に答える
2

私は専門家ではありませんが、これが私の考えです。使用Thread.stop()すると、ThreadDeathすべてのモニターが解放される例外が発生します。例外を引き起こすので、物事の状態に不自然な振る舞いを適用しています。

これらのモニターに依存している他のスレッドは、予期していなかったため、一貫性のない状況に陥る可能性があります。そして、私はあなたがモニターのリリース順序を予想することさえできないと思います。

于 2012-10-31T08:56:41.740 に答える
2

懸念されるのは、スレッドが同期ブロックの途中にあり、オブジェクトのメンバーに対してマルチステップの更新を実行している可能性があることです。スレッドが突然停止した場合、一部の更新は発生しますが、他の更新は発生しないため、オブジェクトの状態によってスレッドが使用できなくなる可能性があります。

ThreadDeath処理によって、アプリケーションが一種のデッドロックへのパスにとどまる可能性Lockのある支援が解放されるのではないかと疑っています。AbstractQueuedSynchronizer

コードの長いシーケンスの任意の論理ポイントで、次を追加するだけです。

if (Thread.interrupted())  {
    throw new InterruptedException();
}

...これは、長時間実行タスクThread.interupt()の実行時に呼び出されたと判断された場合、この時点で実行を終了します。Thread

于 2012-10-31T08:58:02.357 に答える
-1

スレッドを停止する明確な方法はありません。run()メソッドが完了するか、例外が発生するたびに、実際にはstop()メソッドが非推奨になり、ブールフラグ変数を使用してスレッドが停止します。デフォルトでは「false」

于 2013-06-18T08:07:35.557 に答える