1

我想知道如何在java中捕获被上下文切换中断的线程。我有两个线程并排运行,它们都在上下改变相同的 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);
        }
    }
}

这是我从一次运行中得到的:

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

记录进行修改的线程。

每次修改 int 时,存储进行修改的线程。当它与上一个线程不同时,请制作您的 System.out。

否则,您将需要一个允许您中断上下文切换的操作系统。我不知道允许您这样做的操作系统。

于 2011-12-07T18:34:02.830 回答
0

我不认为您可以从线程调度程序(操作系统核心的一部分)监听事件,但您可以使用拉取策略:

  1. 制作一些静态易失性字符串字段
    • 在每个线程中读取这个字段(经常)
    • if field value != "current-thread-name" => print "Context is Switched to "+thread-name
    • 将线程名称写入字段
于 2011-12-07T18:33:16.537 回答