“悪い”への呼び出しからプログラムを分離する方法API?

StackOverflow https://stackoverflow.com/questions/1218790

質問

Javaを使用して(アカデミック)ソフトウェアを開発したとき、かなりひどく実装されていたAPIを使用せざるを得ませんでした。これは、特定の入力データのセットに対するこのAPIの呼び出しが返されない場合があることを意味します。提供されたアルゴリズムは決定論的なものであり、データのセットで終了することもあれば、同じデータのセットで無限ループに陥ることもあるため、これはソフトウェアのバグであるに違いありません...

ただし、APIの修正または再実装は、単に範囲外です。私はソースさえ持っていましたが、APIはドキュメント化されておらずソースのない他のAPIに大きく依存していました。一方、この「悪い」ことは私が抱えていた特定の問題を解決したのはAPIだけだったので、私は本当にそれに固執しなければなりませんでした。

問題は、それが厄介な振る舞いをするAPIを扱う最もクリーンな方法は何ですか?この問題に直面したとき、APIの呼び出しを別のスレッドに入れることにしました。その後、別のスレッドがこのスレッドが終了したかどうかを時々チェックします。一定の時間が経過した場合、 Thread#stop()を使用して処理スレッドを強制終了し、次回に戻ることを期待して、処理を再開します。今、私はこのメソッドが非推奨であり、使用してはならないことを知っています(そして当時も知っていました)。しかし、このアカデミックな文脈では、ソフトウェアをクラッシュさせるのではなく、未定義の状態にする可能性がありました。潜在的に

また、無限ループに陥った処理スレッドを無視することは受け入れられませんでした。これは、ユーザーのマシンを大幅に遅くするかなりCPUを集中的に使用する操作を行ったためです。

私が試みなかった別の方法は、スレッドではなく別のプロセスで処理を開始することです。これは、ソフトウェアを一貫性のない状態にせずにサブプロセスをきれいに終了できるからです。または、新しい SwingWorker クラス(まだ利用できませんでした)が仕事をしたでしょうか? cancel()メソッドがありますが、ドキュメントでは、"このタスクの実行をキャンセルしようとします" と言われているため、信頼できるアプローチのようにも見えません。

役に立ちましたか?

解決

別のプロセスを使用することをお勧めします。 2番目のスレッドが定期的に中断されているかどうかを定期的にチェックしていない限り、1つのスレッドがJavaで2番目のスレッドを強制終了する安全な方法は本質的にありません。

理想的な解決策は、分離株を使用することです。分離は、基本的にJavaアプリが作成、管理、通信できるプライベート仮想マシンです。特に、親アプリは分離株とそのすべてのスレッドを安全に強制終了できます。

参照: JSR-000121アプリケーション分離API仕様-最終リリース

問題は、分離をサポートするJVMを見つけることです。

他のヒント

私はこの種のことを別のプロセスで行うのが大好きです。

サブプロセスを生成し、結果を待ちます。

APIが非決定的である場合、悪いAPIをメインプログラムにするラッパーにタイマースレッドを配置します。

これにより、サブプロセスは常に指定された時間内に終了します。有用な結果を生成するか、失敗を示すシステム終了コードを生成します。

@ S.Lottと@Stephen Cの両方の答えは、このタイプの状況を処理する方法に関してスポットです。実用的なAPI悪いAPIに縛られている状況では、通常、他の理由で販売されたソリューションを選択することで、時間の経過とともに機能を自分のものに置き換える努力をしました。あなたの顧客はあなたの教授ほど寛容ではありません。彼らは単にそれを評価するのではなく、実際にあなたのソフトウェアを使用しなければならないからです。

確かに、ダクトテープを使用することが問題を解決するのに適切な選択である状況があります。しかし、あなたが説明するような貧弱な振る舞いをもたらす場合、それに長く依存しすぎず、実際の修理に取りかかることをお勧めします。

最善のことは、問題のAPIを再実装することです。ただし、あなたが言うように、それは非常に重く、おそらく範囲外のソリューションです。

次善策は、可能であればAPIをラップすることです。基本的に、失敗の原因となるデータセットが何であるかを事前に決定できる場合、決定性を保証するために呼び出しを拒否することができます。同じデータセットで呼び出しを繰り返すと、前の呼び出しで無限にループしたときに終了することがあるため、これはあなたにとってもうまくいくとは思えません。

上記のオプションを使用できない場合:
あなたの現在のスレッドソリューションは、悪い選択のベストだと思います。メソッド呼び出しのプロセスを起動することは、スレッドを使用するよりも安全であっても、パフォーマンスの観点から許容するには重すぎるように思えます。 Thread.stop()は非常に危険ですが、宗教的にロックを防ぐことができれば、それを回避できます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top