9

(テスト中に)同期違反を検出できるように、同期などについてアサーションを作成する良い方法はあるのでしょうか。

これは、たとえば、スレッドセーフではなく、スレッドセーフにならないクラスがある場合に使用されます。何らかの方法で、そのメソッドのいくつかが複数のスレッドから呼び出された場合に通知するアサーション(ログなど)があります。

私は、AWTディスパッチスレッド用に次のようなものを作成できることを切望しています:

public static void checkDispatchThread() {
    if(!SwingUtilities.isEventDispatchThread()) {
        throw new RuntimeException("GUI change made outside AWT dispatch thread");
    }
}

もっと一般的なものが欲しいだけです。問題の説明はそれほど明確ではありませんが、誰かが良いアプローチを持っていることを願っています =)

4

9 に答える 9

2

あなたは聖杯を探していると思います。AFAIKは存在せず、Javaはそのようなアプローチを簡単に作成できる言語ではありません。

「JavaConcurrencyinPractice」には、スレッドの問題のテストに関するセクションがあります。それはそれがどれほど難しいかということに特別な注意を向けます。

于 2008-11-18T14:37:40.173 に答える
2

Javaのスレッドで問題が発生した場合、それは通常、デッドロックの検出に関連しており、同期されたセクションに同時にアクセスしているスレッドを監視するだけではありません。1.5以降にJREに追加されたJMX拡張機能は、これらのデッドロックを検出するのに役立ちます。実際、独自のソフトウェア内でJMXを使用して、検出されたトレースのデッドロックを自動的に検出します。

使い方の例です。

于 2008-11-18T14:41:24.910 に答える
2

IntelliJ IDEAには、便利な並行性検査が多数あります。たとえば、同期コンテキストと非同期コンテキストの両方から同じオブジェクトにアクセスしている場合、非最終オブジェクトなどで同期している場合に警告します。

同様に、FindBugsにも同様のチェックが多数あります。

于 2008-11-18T19:27:29.403 に答える
1

As well as @Fernando's mention of thread deadlocking, another problem with multiple threads is concurrent modifications and the problems it can cause.

One thing that Java does internally is that a collection class keeps a count of how many times it's been updated. And then an iterator checks that value on every .next() against what it was when the interator was created to see if the collection has been updated while you were iterating. I think that principle could be used more generally.

于 2008-11-18T14:56:49.637 に答える
1

Peter Veentjer がブログで紹介している、The Concurrency Detectorと呼ばれるアプローチに興味があるかもしれません。彼がまだこれをオープンソース化したとは思えませんが、彼が説明しているように、基本的な考え方は、AOP を使用してプロファイリングに関心のあるコードを計測し、どのスレッドがどのフィールドに触れたかを記録することです。その後、生成されたログを手動または自動で解析します。

于 2008-11-18T15:59:24.173 に答える
1

スレッドの安全でないクラスを特定できれば、それらが「エスケープ」して複数のスレッドから見えるようになるかどうかを静的分析で判断できる可能性があります。通常、プログラマーは頭の中でこれを行いますが、明らかにこの点で間違いを犯しがちです。ツールは、同様のアプローチを使用できる必要があります。

とはいえ、あなたが説明したユースケースからすると、スレッドを覚えてそれに対してアサーションを行うのと同じくらい簡単なことのように思えますが、ニーズには十分かもしれません。

class Foo {

  private final Thread owner = Thread.currentThread();

  void x() {
    assert Thread.currentThread() == owner;
    /* Implement method. */
  }

}

所有者参照は、アサーションが無効になっている場合でも設定されているため、完全に「無料」というわけではありません。また、このボイラープレートで多くのクラスを混乱させたくありません。

Thread.holdsLock (Object)メソッドも役立つ場合があります。

于 2008-11-18T16:00:42.253 に答える
1

ConTestまたはCovertityを試す

どちらのツールもコードを分析して、データのどの部分がスレッド間で共有される可能性があるかを判断し、コードを計測して (コンパイルされたクラスに余分なバイトコードを追加します)、2 つのスレッドが同時に一部のデータを変更しようとしたときにコードが壊れるかどうかをチェックします。 . その後、2 つのスレッドが何度も実行され、そのたびにわずかに異なる時間オフセットで開始され、アクセス パターンの可能な組み合わせが多数取得されます。

また、次の質問も確認してください:マルチスレッド アプリケーションの単体テストを行いますか?

于 2008-11-18T15:13:40.337 に答える
0

あなたが与える特定の例のために、SwingLabsはイベントスレッド違反とハングを検出するためのいくつかのヘルパーコードを持っています。 https://swinghelper.dev.java.net/

しばらく前に、私はJProbeJavaプロファイリングツールを使用していました。彼らのツールの1つ(threadalyzer?)は、スレッド同期違反を探しました。彼らのウェブページを見ると、その名前のツールや私が覚えているツールはまったく見当たりません。しかし、あなたは見てみたいかもしれません。 http://www.quest.com/jprobe/performance-home.aspx

于 2008-11-18T14:33:54.207 に答える
-1

NetbeansプロファイラまたはJConsoleを使用して、スレッドのステータスを詳細に確認できます

于 2008-11-18T15:44:43.533 に答える