27

多くの複雑な対話を伴う、かなり大規模な Swing GUI の保守と構築を支援しています。コードの別の場所で何らかの競合状態が発生して奇妙な状態になった結果、バグを修正していることに気付くことがよくあります。

コード ベースが大きくなるにつれて、どのメソッドにスレッド化の制限があるかをドキュメントで指定する方法の一貫性が失われていることがわかりました。最も一般的なのは、Swing EDT で実行する必要があるメソッドです。同様に、仕様によって EDT でどの (カスタム) リスナーに通知されるかを知り、静的な認識を提供すると便利です。

そのため、これはアノテーションを使用して簡単に適用できるものであるべきだと思いました。驚いたことに、少なくとも 1 つの静的分析ツールCheckThreadが存在し、アノテーションを使用してこれを実現しています。特定のスレッド (最も一般的には EDT) に限定されるメソッドを宣言できるようで、そのスレッドに限定されていると宣言せずにそのメソッドを呼び出そうとするメソッドにフラグを立てます。

したがって、表面的には、これは、ソースとビルド サイクルへの簡単な追加であり、巨大なゲインのように見えます。私の質問は次のとおりです。

  • CheckThread または同様のライブラリを使用してスレッド化の制約を適用する人々の成功例はありますか? 失敗談は? なぜ成功/失敗したのですか?
  • これは理論的には良いですか? 理論上の欠点はありますか?
  • これは実際に良いですか? その価値はありますか? それはどのような価値をもたらしましたか?
  • 実際に機能する場合、これをサポートするための優れたツールは何ですか? CheckThread を見つけたばかりですが、同じことを行う他のツールを見つけるために何を探しているのか完全にはわかりません。

それが私たちにとって正しいかどうかは、私たちのシナリオ次第です。しかし、実際にこのようなものを使用している人は聞いたことがありません。正直なところ、一般的なブラウジングではあまり定着していないようです。だから私はなぜだろうと思っています。

4

3 に答える 3

8

この答えは、あなたの質問の理論的側面により焦点を当てています。

基本的に、「このメソッドは特定のスレッドでのみ実行されます」というアサーションを作成しています。このアサーションは、他のアサーションと実際には違いはありません(「このメソッドはパラメーターXに対して17未満の整数のみを受け入れます」)。問題は

  • そのような主張はどこから来るのですか?
  • 静的アナライザーはそれらをチェックできますか?
  • このような静的アナライザーはどこで入手できますか?

意図を知っているのはソフトウェア設計者だけなので、ほとんどの場合、そのような主張はソフトウェア設計者からのものでなければなりません。これの伝統的な用語は「契約による設計」ですが、ほとんどのDBCスキームは、現在のプログラムの状態を超えているだけです(Cの主張マクロ)そしてそれらは実際にプログラムの過去と未来の状態(「一時的なアサーション」)を超えている必要があります。たとえば、「このルーチンはストレージのブロックを割り当て、最終的にはコードの一部がそれを割り当て解除します」。アサーションが何であるかをヒューリスティックに決定しようとするツールを構築できます(たとえば、Englerのアサーション誘導作業。他の人はこの分野で作業を行っています)。これは便利ですが、誤検知が問題になります。実際問題として、そのようなアサーションをコーディングするように設計者に依頼することは、特に面倒なことではないように思われ、非常に優れた長期的なドキュメントです。このようなアサーションを特定の「コントラクト」言語構造でコーディングするか、ifステートメント( "if Debug && Not(アサーション)次に、Fail(); ")またはアノテーションでそれらを非表示にすることは、実際には単に便利な問題です。言語がそのようなアサーションを直接コーディングできる場合は便利です。

このようなアサーションを静的にチェックすることは困難です。現在の状態のみに固執する場合、アサーションを満たすために必要な情報はアプリケーションの別の部分によって作成されたデータからのものである可能性が高いため、静的アナライザーはアプリケーション全体の完全なデータフロー分析を行う必要があります。(あなたの場合、「EDT内」シグナルは、アプリケーションのコールグラフ全体を分析して、EDTスレッドではないスレッドからのメソッドにつながるコールパスがあるかどうかを確認する必要があります)。時間プロパティを使用する場合、静的チェックには、さらに何らかの状態空間検証ロジックが必要になります。これらは現在でもほとんど研究ツールです。これらすべての機械を使用しても、静的アナライザーは通常、分析において「保守的」である必要があります。彼らができるなら」

そのようなアナライザーはどこで入手できますか?必要なすべての機械を考えると、それらを構築するのは難しいので、それらはまれであると期待する必要があります。誰かがそれを作ったなら、素晴らしい。そうでない場合...原則として、これを最初から自分で行うことは望ましくありません。長期的な最善の希望は、そのようなアナライザーを構築するための汎用プログラム分析機構を利用可能にして、すべてのインフラストラクチャーの構築コストを償却することです。(私はプログラムアナライザーツールの基盤を構築します。DMSソフトウェアリエンジニアリングツールキットを参照してください)。

このような静的アナライザーの構築を「簡単」にする1つの方法は、それらが処理するケースを、CheckThreadなどの狭い範囲に制限することです。CheckThreadが現在行っていることを正確に実行することを期待しており、これほど強力になる可能性は低いでしょう。

「アサート」マクロやその他の動的な「現在の状態」チェックが一般的である理由は、単純なランタイムテストで実際に実装できるためです。それはかなり実用的です。ここでの問題は、失敗した状態につながるパスを実行できないことです。したがって、動的分析の場合、障害が検出されないことは、実際には正確さの証拠ではありません。まだ気持ちいい。

結論:静的アナライザーと動的アナライザーにはそれぞれ長所があります。

于 2010-07-05T17:32:47.900 に答える
3

静的分析ツールは試していませんが、AspectJ を使用して、java.awt または javax.swing のコードが EDT の外部で呼び出されたときに実行時に検出する単純なアスペクトを作成しました。コード内でSwingUtilities.invokeLater(). QA サイクル全体でこの側面を有効にして実行し、リリースの直前にオフにします。

于 2010-06-28T03:26:32.180 に答える
2

要求どおり、これは特に Java や EDT に関係するものではありませんが、C/C++ 用の Coverity の同時実行静的解析チェッカーで良い結果が得られました。それほど複雑でないチェッカーよりも誤検知率が高かったのですが、スレッド化のバグをテストで見つけるのがいかに難しいかを考えると、コード所有者はそれを我慢してくれているようでした。詳細は機密情報ですので、恐れ入りますが、Dawson Engler の公開論文 (「逸脱した動作としてのバグ」など) は、「コードの次の «N» 個のインスタンスは、« を実行する前に «X» を実行するという一般的なアプローチに非常に優れています。 Y»,; このインスタンスはそうではありません。」</p>

于 2010-06-28T14:55:06.847 に答える