2010-04-11 7 views
2

Ma tâche consiste à simuler l'activité de deux personnes. Chacun d'eux a peu d'activités à effectuer dans un temps aléatoire: rapide (0-5s), moyen (5-10s), lent (10-20s) et très lent (20-30s). Chaque personne effectue sa tâche indépendamment dans le même temps. Au début de la nouvelle tâche, je devrais imprimer l'heure au hasard, commencer la tâche et ensuite, après que le temps a passé, montrer l'heure de la prochaine tâche et la démarrer. J'ai écrit la fonction run() qui compte le temps, mais maintenant on dirait que les threads se font l'un après l'autre et pas en même temps ou peut-être qu'ils sont simplement imprimés de cette façon.exécution de plusieurs threads en Java

public class People{ 
    public static void main(String[] args){ 
    Task tasksA[]={new Task("washing","fast"), 
       new Task("reading","slow"), 
       new Task("shopping","medium")}; 
    Task tasksM[]={new Task("sleeping zzzzzzzzzz","very slow"), 
       new Task("learning","slow"), 
       new Task(" :** ","slow"), 
       new Task("passing an exam","slow") }; 
    Task tasksJ[]={new Task("listening music","medium"), 
       new Task("doing nothing","slow"), 
       new Task("walking","medium") }; 

    BusyPerson friends[]={ new BusyPerson("Alice",tasksA), 
          new BusyPerson("Mark",tasksM), 
          new BusyPerson("John",tasksJ)}; 

    System.out.println("STARTING....................."); 
    for(BusyPerson f: friends) 
     (new Thread(f)).start(); 
    System.out.println("DONE........................."); 
    } 
} 

class Task { 

    private String task; 
    private int time; 
    private Task[]tasks; 

    public Task(String t, String s){ 
     task = t;  
     Speed speed = new Speed(); 
     time = speed.getSpeed(s); 
    } 

    public Task(Task[]tab){ 
     Task[]table=new Task[tab.length]; 
     for(int i=0; i < tab.length; i++){ 
      table[i] = tab[i]; 
     } 
     this.tasks = table; 
    } 
} 

class Speed { 

    private static String[]hows = {"fast","medium","slow","very slow"}; 
    private static int[]maxs = {5000, 10000, 20000, 30000}; 

    public Speed(){ 
    } 

    public static int getSpeed(String speedString){ 
     String s = speedString; 
     int up_limit=0; 
     int down_limit=0; 
     int time=0; 
//get limits of time 
     for(int i=0; i<hows.length; i++){ 
      if(s.equals(hows[i])){ 
       up_limit = maxs[i]; 
       if(i>0){ 
        down_limit = maxs[i-1]; 
       } 
       else{ 
        down_limit = 0; 
       } 
      } 
     } 
//get random time within the limits 
     Random rand = new Random(); 
     time = rand.nextInt(up_limit) + down_limit; 

    return time; 
    } 

} 

class BusyPerson implements Runnable { 
    private String name; 
    private Task[] person_tasks; 
    private BusyPerson[]persons; 

    public BusyPerson(String s, Task[]t){ 
     name = s; 
     person_tasks = t; 
    } 

    public BusyPerson(BusyPerson[]tab){ 
     BusyPerson[]table=new BusyPerson[tab.length]; 
     for(int i=0; i < tab.length; i++){ 
      table[i] = tab[i]; 
     } 
     this.persons = table; 
    } 

public void run() { 
    int time = 0; 
    double t1=0; 

    for(Task t: person_tasks){ 
     t1 = (double)t.time/1000; 
     System.out.println(name+" is... "+t.task+" "+t.speed+ 
       " ("+t1+" sec)"); 
     while (time == t.time) { 
      try { 
       Thread.sleep(10); 
      } catch(InterruptedException exc) { 
       System.out.println("End of thread."); 
       return; 
      } 
      time = time + 100; 
     } 
    } 

} 
} 

Et ma sortie:

STARTING..................... 
DONE......................... 
Mark is... sleeping zzzzzzzzzz   very slow   (36.715 sec) 
Mark is... learning   slow   (10.117 sec) 
Mark is...  :**    slow   (29.543 sec) 
Mark is... passing an exam   slow   (23.429 sec) 
Alice is... washing   fast   (1.209 sec) 
Alice is... reading   slow   (23.21 sec) 
Alice is... shopping   medium   (11.237 sec) 
John is... listening music   medium   (8.263 sec) 
John is... doing nothing   slow   (13.576 sec) 
John is... walking   medium   (11.322 sec) 

Alors qu'il devrait ressembler à ceci:

STARTING..................... 
    DONE......................... 
    John is... listening music  medium  (7.05 sec) 
    Alice is... washing  fast (3.268 sec) 
    Mark is... sleeping zzzzzzzzzz  very slow (23.71 sec) 
    Alice is... reading  slow (15.516 sec) 
    John is... doing nothing slow (13.692 sec) 
    Alice is... shopping medium  (8.371 sec) 
    Mark is... learning slow (13.904 sec) 
    John is... walking  medium  (5.172 sec) 
    Mark is... :**   slow (12.322 sec) 
    Mark is... passing an exam  very slow (27.1 sec) 
+1

@owca: +1 ... Question bien écrite et plutôt cool. Je ne comprends pas pourquoi les gens pensent que certaines réponses sont dignes d'être votées mais ne votent pas la question. – SyntaxT3rr0r

Répondre

3

Il semble que votre boucle d'attente a la condition erronée de terminaison, en utilisant time == t.time au lieu de time <= t.time. En outre, il semble augmenter de 100 au lieu de 10 dans chaque itération.

De même, vous devez réinitialiser time avant chaque boucle.

En d'autres termes, la boucle

while (time == t.time) { 
    try { 
     Thread.sleep(10); 
    } catch(InterruptedException exc) { 
     System.out.println("End of thread."); 
     return; 
    } 
    time = time + 100; 
} 

devrait probablement

time = 0; 
while (time <= t.time) { 
    try { 
     Thread.sleep(10); 
    } catch(InterruptedException exc) { 
     System.out.println("End of thread."); 
     return; 
    } 
    time += 10; 
} 

ou utiliser une boucle à la place:

for (int time = 0; time <= t.time; time += 10) { 
    try { 
     Thread.sleep(10); 
    } catch(InterruptedException exc) { 
     System.out.println("End of thread."); 
     return; 
    } 
} 

Cependant, il n'y a vraiment aucune raison dormir par incréments de 10 millisecondes. En outre, Thread.sleep() peut être inexact. Il est préférable d'essayer toute la période en une fois, et vérifier l'horloge après.

long timeToWakeup = System.currentTimeMillis() + t.time; 
long sleepMs = t.time; 
while (sleepMs > 0) { 
    try { 
     Thread.sleep(sleepMs); 
    } catch(InterruptedException exc) { 
     System.out.println("End of thread."); 
     return; 
    } 
    sleepMs = timeToWakeup - System.currentTimeMillis()); 
} 
+0

merci, maintenant cela fonctionne parfaitement. – owca