简体   繁体   English

确定Java程序的确定性线程执行

[英]Determining deterministic thread execution of a Java program

I wrote a very simple toy program to complete the execution of a task inside a thread as per the timing requirements specified by a user. 我编写了一个非常简单的玩具程序,根据用户指定的时间要求来完成线程内任务的执行。 The code and the sample output is below. 代码和示例输出如下。 What happens is that everytime you run the code, the task completion times would be within a + delta range of the time specified by the user. 发生的情况是,每次您运行代码时,任务完成时间将在用户指定的时间的+增量范围内。 For eg if the user wants to complete the program in 5 secs it may complete in 5093 or 5012 ms according to the CPU the code runs on. 例如,如果用户要在5秒钟内完成程序,则根据运行代码的CPU,它可能在5093或5012毫秒内完成。 I want to add in some code which can automatically determine the lowest latency that a particular CPU will provide for a particular version of the JVM. 我想添加一些代码,这些代码可以自动确定特定CPU将为特定版本的JVM提供的最低延迟。 Based on that instrumentation code, a value of delta can be added to the line like : if (( taskRunTime > patience+delta) && t.isAlive()) so that the system brings in more precision to the task execution timing. 基于该检测代码,可以将delta值添加到以下行: if (( taskRunTime > patience+delta) && t.isAlive())以便系统为任务执行定时带来更高的精度。 Please give some suggestions. 请给一些建议。

Code: 码:

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");

    }
}

Sample output from a Intel Centrino 1.7 Ghz machine ( Java HotSpot(TM) Client VM (build 10.0-b23, mixed mode) ) 来自Intel Centrino 1.7 Ghz计算机(Java HotSpot(TM)客户端VM(内部版本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!

I've also written some stuff about the behaviour of Thread.sleep and other stuff related to threading and Java that might be of use. 我还写了一些有关Thread.sleep行为的内容,以及与线程和Java相关的其他有用内容。

The short answer is that the granularity you're going to get will depend on a lot of factors, some of which are dynamic. 简短的答案是,您要获得的粒度取决于许多因素,其中一些是动态的。 Instrumenting it as you suggest is one way forward. 按照您的建议进行检测是前进的一种方法。 Things you need to think about instrumenting include: 您需要考虑的有关检测的事项包括:

  • behaviour of actual sleep vs requested under given conditions (see my article for an illustration of some typical behaviours under different conditions) 在给定条件下的实际睡眠行为与要求的行为(请参阅我的文章,以了解在不同条件下的一些典型行为)
  • thread interrupt latency under given conditions (will depend partly on CPU load, scheduling policy of system...) 给定条件下的线程中断延迟(将部分取决于CPU负载,系统的调度策略...)

Also, consider improving the control loop so that it essentially (a) sleeps for the required time (in a loop, ensuring the time is slept for), and (b) interrupts the thread after the timeout. 另外,请考虑改进控制循环,以使该循环本质上是(a)睡眠所需的时间(在一个循环中,确保睡眠了一定的时间),并且(b)在超时后中断线程。

BTW, always use System.nanoTime() for your timings. 顺便说一句,请始终使用System.nanoTime()进行计时。 Otherwise, you're just confusing things because of the poor granularity of System.currentTimeMillis() under some systems. 否则,由于某些系统中System.currentTimeMillis()的粒度不佳,您只会感到困惑。

I would suggest you look in to Java Real Time: http://en.wikipedia.org/wiki/Real_time_Java And also check out: http://java.sun.com/j2se/1.5.0/docs/guide/concurrency/overview.html 我建议您浏览Java实时: http : //en.wikipedia.org/wiki/Real_time_Java并查看: http : //java.sun.com/j2se/1.5.0/docs/guide/concurrency /overview.html

You shouldn't be writing you own threads after Java 1.5 Java 1.5之后,您不应该编写自己的线程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM