1

Java で Context Switch によって中断されているスレッドをキャッチする方法を知りたいです。2 つのスレッドが並行して実行されており、どちらも同じ int を上下に変更しています。レポートのために、スイッチをキャッチして何かを行う方法を知りたいと思います。(例えば、それが起こったときに単純な System.out を作成します) ありがとう!

4

3 に答える 3

3

アプリケーションに関する限り、コンテキスト スイッチは目に見えません。アプリケーションに通知するシグナルやメッセージは送信されません。

アプリケーションをひっくり返す可能性があるのは、タイミングだけです。たとえば、タイトなループを繰り返し計測すると、中断されなかった実行に比べて長い時間が必要になるため、ループの実行時に発生するコンテキスト スイッチを (信頼性が低く) 検出できる可能性があります。残念ながら、これは C などのコンパイル済み言語でのみ可能です。仮想マシンを使用する Java などの言語では、このようなことを確実に検出することは事実上不可能です。ガベージコレクターが動いています。

さらに、すべてのシステム コール (特に、このようなイベントをログに記録するために使用するような I/O コール) は、暗示的なコンテキスト スイッチを引き起こすことが非常に多く、これにより、実行したいことがすべて中断される可能性があることに注意してください。

そもそもなんでそんなこと知りたいの?特にJavaアプリケーションからですか?

編集:

さて、同期の問題を作成した後であれば、これが私のバージョンです。

public class Test {
    public static long count = 0;

    public static void main(String[] args) {
        for (int run = 0; run < 5; ++run) {
            Test.count = 0;

            Thread[] threads = new Thread[10];

            for (int i = 0; i < threads.length; ++i) {
                threads[i] = new Thread(new Runnable() {
                    public void run() {
                        for (long i = 0; i < (10 * 1000 * 1000 * 1000); ++i) {
                            Test.count += 1;
                        }
                    }
                });
            }

            for (int i = 0; i < threads.length; ++i) {
                threads[i].start();
            }

            for (int i = 0; i < threads.length; ++i) {
                try {
                    threads[i].join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            System.out.println(Test.count);
        }
    }
}

1回の実行で得たものは次のとおりです。

1443685504
1439908180
1461384255
1477413204
1440892041
于 2011-12-07T18:33:23.860 に答える
2

変更を行ったスレッドを記録します。

int が変更されるたびに、変更を行うスレッドを保存します。前のスレッドと異なる場合は、System.out を作成してください。

それ以外の場合は、コンテキスト スイッチを中断できるオペレーティング システムが必要になります。それを可能にするオペレーティングシステムを私は知りません。

于 2011-12-07T18:34:02.830 に答える
0

スレッドスケジューラ(OSコアの一部)からイベントをリッスンできるとは思いませんが、プル戦略を使用できます:

  1. いくつかの静的な揮発性文字列フィールドを作成します
    • すべてのスレッドでこのフィールドを読み取ります (非常に頻繁に)
    • If field value != "current-thread-name" => print "Context is Switched to "+thread-name"
    • フィールドにスレッド名を書き込む
于 2011-12-07T18:33:16.537 に答える