1 votes

Détermination de l'exécution déterministe des threads d'un programme Java

J'ai écrit un programme jouet très simple pour compléter l'exécution d'une tâche à l'intérieur d'un thread selon les exigences de temps spécifiées par un utilisateur. Le code et l'exemple de sortie sont ci-dessous. Ce qui se passe, c'est qu'à chaque fois que vous exécutez le code, les temps d'exécution de la tâche se situent dans une fourchette de + delta par rapport au temps spécifié par l'utilisateur. Par exemple, si l'utilisateur souhaite terminer le programme en 5 secondes, il se terminera en 5093 ou 5012 ms selon l'unité centrale sur laquelle le code s'exécute. Je veux ajouter un code qui peut automatiquement déterminer la latence la plus faible qu'un processeur particulier fournira pour une version particulière de la JVM. Sur la base de ce code d'instrumentation, une valeur de delta peut être ajoutée à la ligne comme : if (( taskRunTime > patience+delta) && t.isAlive()) de sorte que le système apporte plus de précision au moment de l'exécution de la tâche. Veuillez nous faire part de vos 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");

    }
}

Exemple de sortie d'une machine Intel Centrino 1.7 Ghz ( Java HotSpot(TM) Client VM (build 10.0-b23, mixed mode) )

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!

3voto

Neil Coffey Points 13408

J'ai également écrit quelques articles sur le comportement de Thread.sleep et d'autres choses liées au threading et à Java qui pourraient être utiles.

En bref, la granularité que vous obtiendrez dépendra de nombreux facteurs, dont certains sont dynamiques. L'instrumentation, comme vous le suggérez, est un moyen d'avancer. Les éléments à prendre en compte pour l'instrumentation sont les suivants :

  • le comportement du sommeil réel par rapport au sommeil demandé dans des conditions données (voir mon article pour une illustration de certains comportements typiques dans différentes conditions).
  • le temps de latence des interruptions de threads dans des conditions données (dépendra en partie de la charge du CPU, de la politique d'ordonnancement du système...)

En outre, il convient d'améliorer la boucle de contrôle de manière à ce qu'elle (a) s'endorme pendant la durée requise (dans une boucle, en veillant à ce que la durée s'endorme) et (b) interrompe le fil d'exécution après l'expiration du délai.

BTW, utilisez toujours la fonction System.nanoTime() pour vos calculs de temps. Sinon, vous ne faites que vous embrouiller en raison de la faible granularité de System.currentTimeMillis() sous certains systèmes.

0voto

Pyrolistical Points 12457

Je vous suggère de vous intéresser à Java Real Time : http://en.wikipedia.org/wiki/Real_time_Java A consulter également : http://java.sun.com/j2se/1.5.0/docs/guide/concurrency/overview.html

Vous ne devriez pas écrire vos propres threads après Java 1.5

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X