【问题标题】:Determining deterministic thread execution of a Java program确定 Java 程序的确定性线程执行
【发布时间】:2010-11-18 18:50:18
【问题描述】:

我编写了一个非常简单的玩具程序,按照用户指定的时序要求,在线程内完成任务的执行。代码和示例输出如下。发生的情况是,每次运行代码时,任务完成时间都会在用户指定时间的 + delta 范围内。例如,如果用户想在 5 秒内完成程序,根据代码运行的 CPU,它可能在 5093 或 5012 毫秒内完成。我想添加一些代码,这些代码可以自动确定特定 CPU 将为特定版本的 JVM 提供的最低延迟。基于该检测代码,可以将 delta 值添加到如下行:if (( taskRunTime > patience+delta) && t.isAlive()),以便系统为任务执行时间带来更精确的结果。请给点建议。

代码:

public class ThreadExample 
{


    static void threadMessage(String message) 
    {
        String threadName = Thread.currentThread().getName();
        System.out.format("%s: %s%n", threadName, message);
    }

    private static class MessageLoop implements Runnable 
    {
        public void run() 
        {
            String importantInfo[] = 
            {
                "A new integrated approach to programming",
                "The innovative approach of the system",
                "The input of a tracking system",
                "A simulation system is then used for collision checking"
            };
            try 
                {
                    for (int i = 0; i < importantInfo.length; i++) 
                        {

                            Thread.sleep(4000);
                            threadMessage(importantInfo[i]);
                        }
                } 
                catch (InterruptedException e) 
                    {
                        threadMessage("I wasn't done!");
                    }
        }
    }

    public static void main(String args[]) throws InterruptedException 
    {


        //Delay, in milliseconds before we interrupt MessageLoop
        long patience = 1000 * 60 * 60;

        //If command line argument present, gives patience in seconds.
        if (args.length > 0) 
        {
            try {
                patience = Long.parseLong(args[0]) * 1000;
            } catch (NumberFormatException e) {
                System.err.println("Argument must be an integer.");
                System.exit(1);
            }

        }

        threadMessage("Starting MessageLoop thread");
        long startTime = System.currentTimeMillis(),taskRunTime=0;
        Thread t = new Thread(new MessageLoop());
        t.start();

        threadMessage("Waiting for MessageLoop thread to finish");
        //loop until MessageLoop thread exits
        while (t.isAlive()) 
        {
            threadMessage("Still waiting...");
            //Wait maximum of 1 second for MessageLoop thread to finish.
            t.join(100);
            taskRunTime=System.currentTimeMillis() - startTime;
            if (( taskRunTime > patience) && t.isAlive()) 
            {
                threadMessage("Tired of waiting...task is running longer than the patience you set or the default!");
                t.interrupt();
                t.join();
            }

        }
        threadMessage("Finally out of thread!");
        System.out.println("Time to complete task="+taskRunTime+"ms");

    }
}

来自 Intel Centrino 1.7 Ghz 机器的示例输出(Java HotSpot(TM) Client VM(build 10.0-b23,混合模式))

java -jar ThreadExample.jar 5
main: Starting MessageLoop thread
main: Waiting for MessageLoop thread to finish
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
Thread-0: A new integrated approach to programming
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Tired of waiting...task is running longer than the patience you set or the default!
Thread-0: I wasn't done!
main: Finally out of thread!

【问题讨论】:

    标签: java multithreading real-time


    【解决方案1】:

    我还写了一些关于 behaviour of Thread.sleep 的内容以及其他可能有用的与线程和 Java 相关的内容。

    简短的回答是,您将获得的粒度取决于很多因素,其中一些是动态的。按照您的建议对其进行检测是前进的一种方式。关于检测需要考虑的事项包括:

    • 在给定条件下实际睡眠与要求睡眠的行为(有关不同条件下一些典型行为的说明,请参阅我的文章)
    • 给定条件下的线程中断延迟(部分取决于 CPU 负载、系统的调度策略...)

    另外,考虑改进控制循环,使其本质上 (a) 休眠所需的时间(在循环中,确保时间已休眠),并且 (b) 在超时后中断线程。

    顺便说一句,请始终使用 System.nanoTime() 作为您的计时。 否则,由于 System.currentTimeMillis() 在某些系统下的粒度很差,您只会感到困惑。

    【讨论】:

      【解决方案2】:

      我建议您查看 Java Real Time:http://en.wikipedia.org/wiki/Real_time_Java 并查看:http://java.sun.com/j2se/1.5.0/docs/guide/concurrency/overview.html

      您不应该在 Java 1.5 之后编写自己的线程

      【讨论】:

      • 所以你建议使用并发工具?我在哪里可以找到编写允许确定性执行并发任务的代码的示例?在这个特殊的简单案例中,我并不关心任务协调和并发性,因为我正在确定确定性。当然,一旦我安排了多个任务,问题就会出现,但我想先从简单的事情开始。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-22
      • 2011-04-07
      • 1970-01-01
      • 1970-01-01
      • 2011-04-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多