1

何らかの理由で、これの出力:

 public void msgNeedParts() {
    // Blabla...
    System.out.println(name + ": Try to print 'tasks'...");
    synchronized(tasks) {
        System.out.println(name + ": Tasks--" + tasks);
        System.out.println(name + ": Did I manage to print it?");
        tasks.add(new BinToDump(feeder, binNum));
    }
    stateChanged();
 }

「GantryAgent: Try to print 'tasks'...」だけが出力されますが、次のメッセージは出力されません。同期されたリスト「タスク」にアクセスしようとすると、スレッドが何らかの形で「スタック」すると推測していますが、なぜこれが起こっているのかわかりません。

「タスク」は次のように宣言および初期化されました。

private List<BinToDump> tasks = 
    Collections.synchronizedList(new ArrayList<BinToDump>());

誰かが私が欠けているものを指摘できますか?

ああ!私は犯人を持っているのではないかと疑っています:

    /* If nothing left to do, return to original position. */

    synchronized (tasks) {

        if (tasks.isEmpty()) {

            doReturnToOriginalPos();

        }

    }

私のスケジューラ (これはエージェントの設計です) で、「タスク」が空かどうかを確認してから、doReturnToOriginalPos() を呼び出します。たぶん、これは他の方法がそれを変更する機会を得られないほど速く何度も起こっているのでしょうか?

それは確かに問題でした!スケジューラーで非常に高速に呼び出され続けたため、他の何も「タスク」にアクセスできませんでした。助けてくれてありがとう!

4

2 に答える 2

6

何かがタスクをロックしています。これがどのような種類のアプリケーションであるかによって、システムの完全なスタック ダンプを取得できるはずですが、方法は異なります。たとえば、ほとんどの Windows ベースのアプリケーション サーバーでは CTRL-Break でこれが行われると思います。また、Linux では SIGQUIT を送信しても同じことが行われると思います。

スタック ダンプを取得したら、それを調べて、そのオブジェクトをロックしている他のスレッドを見つけようとすることができます。

同じ最終目標のために、 VisualVMを使用してスタック ダンプを取得することもできます。

Java VisualVM を使用して、ローカル アプリケーションの実行中にスレッド ダンプ (スタック トレース) を取得できます。スレッド ダンプを取得しても、アプリケーションは停止しません。スレッド ダンプを出力すると、Java スレッドのスレッド状態を含むスレッド スタックが出力されます。

Java VisualVM でスレッド ダンプを出力すると、ツールはアプリケーションのアクティブなスレッドのスタック トレースを出力します。Java VisualVM を使用してスレッド ダンプを取得すると、アプリケーション用のコマンドライン コンソールがない場合に非常に便利です。スタック トレースを使用すると、デッドロックやアプリケーションのハングなど、さまざまな問題を診断するのに役立ちます。

于 2009-12-01T08:40:39.770 に答える
2

別のスレッドが同期ロックを保持している可能性はありtasksますか?

于 2009-12-01T08:34:57.660 に答える