2009-08-11 6 views
1

J'ai écrit un programme jouet très simple pour terminer l'exécution d'une tâche dans un thread selon les exigences de temps spécifiées par un utilisateur. Le code et la sortie de l'échantillon sont ci-dessous. Ce qui se passe est que chaque fois que vous exécutez le code, les temps d'achèvement de la tâche se situeraient dans une plage delta + du temps spécifié par l'utilisateur. Par exemple, si l'utilisateur veut terminer le programme en 5 secondes, il peut terminer en 5093 ou 5012 ms en fonction de la CPU, le code fonctionne. Je veux ajouter dans un code qui peut déterminer automatiquement la latence la plus basse qu'un CPU particulier fournira pour une version particulière de la JVM. Basé sur ce code d'instrumentation, une valeur de delta peut être ajoutée à la ligne comme: if ((taskRunTime > patience+delta) && t.isAlive()) afin que le système apporte plus de précision à la synchronisation de l'exécution de la tâche. S'il vous plaît donner quelques suggestions.Détermination de l'exécution de threads déterministes d'un programme Java

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'un processeur Intel Centrino ordinateur 1.7 Ghz (Java HotSpot (TM) Client VM (build 10.0-b23, mode mixte))

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! 

Répondre

0

Je suggère vous regardez dans le temps réel de Java: http://en.wikipedia.org/wiki/Real_time_Java Et vérifiez également: http://java.sun.com/j2se/1.5.0/docs/guide/concurrency/overview.html

Vous ne devriez pas écrire vos propres fils après Java 1 .5

+0

Vous suggérez donc l'utilisation des utilitaires de simultanéité? Où puis-je trouver des exemples d'écriture de code permettant l'exécution déterministe de tâches simultanées? Dans ce cas particulièrement simple, je ne m'inquiète pas beaucoup de la coordination des tâches et de la simultanéité, car je dois déterminer le déterminisme. Bien sûr, le problème viendrait dès que j'ai plusieurs tâches planifiées, mais je veux commencer avec des choses simples en premier. – iceman

3

J'ai aussi écrit quelques trucs sur le behaviour of Thread.sleep et d'autres trucs liés au threading et Java qui pourraient être utiles. La réponse courte est que la granularité que vous obtiendrez dépendra de nombreux facteurs, dont certains sont dynamiques. L'instrumentation que vous suggérez est une voie à suivre. Ce que vous devez penser à instrumenter comprennent:

    comportement
  • du sommeil réel par rapport demandé dans des conditions données (voir mon article pour une illustration de certains comportements typiques dans différentes conditions)
  • latence
  • d'interruption de fil dans des conditions données (sera dépendent en partie de la charge CPU, la politique de planification du système ...)

en outre, envisager d'améliorer la boucle de contrôle afin qu'il essentiellement (a) dort pendant le temps nécessaire (dans une boucle, assurant le temps est dormit), et (b) interrompt le thread après le timeout.

BTW, utilisez toujours System.nanoTime() pour vos horaires. Sinon, vous ne faites que créer de la confusion à cause de la faible granularité de System.currentTimeMillis() sous certains systèmes.