2010-12-07 7 views
5

Je viens juste de commencer à apprendre des sujets et à en arriver à des malentendus sur leur fonctionnement.Faire en sorte que les fils fonctionnent correctement

Voici ma classe:

public class MyThread extends Thread { 
    private static int NUM = 0; 
    private int id; 

    public MyThread() { 
     id = NUM++; 
    } 

    public static void main(String[] args) { 
     for (int i = 0; i < 10; i++) { 
      new MyThread().start(); 
     } 
    } 

    public void run() { 
     System.out.println(id + " started"); 

     try { 
      Process p = Runtime.getRuntime().exec("javac -version"); 
      p.waitFor(); 
     } catch (Exception e) { 
      System.out.println("Call a doc!"); 
     } 

     System.out.println(id + " finished"); 
    } 
} 

/* 
Just a sidenote. 
I am creating new javac process just to slow an application down. 
Simple System.out.println(…) is a way faster. 
*/ 

Pourquoi je reçois toujours tous messages "... a commencé" dans un premier temps et après que les messages "... finis"? Peu importe combien de fils ai-je commencé, je vois toujours:

0 started 
1 started 
2 started 
3 started 
4 started 
5 started 
6 started 
7 started 
8 started 
9 started 
0 finished 
1 finished 
3 finished 
4 finished 
8 finished 
5 finished 
2 finished 
6 finished 
9 finished 
7 finished 

est-ce pas le but de threads à paralléliser l'exécution?
Peut-être que j'ai besoin de synchroniser quelque chose? Ou fait une erreur négligente? Ou…?
Expliquez, s'il vous plaît.

MISE À JOUR:

Pourquoi ne vois-je pas, disons que:

0 started 
1 started 
0 finished 
2 started 
1 finished 
2 finished 

Merci à tous pour le traitement.

+0

votre anglais va bien. Bonne question. – sje397

+0

@ sje397 Merci, monsieur! – Mick

Répondre

2

Les fils sont parallèles. Sinon, vous verriez chaque thread "terminé" avant que le prochain "démarré"

Un moyen simple de ralentir un thread est d'utiliser Thread.sleep (10 * 1000); dormir pendant 10 secondes (10 000 millisecondes)

EDIT: un moyen simple de voir l'entrelacement des threads est d'avoir un pool de threads de taille fixe.

ExecutorService pool = Executors.newFixedThreadPool(4); 
for (int i = 0; i < 10; i++) { 
    final int id = i; 
    pool.submit(new Callable<Void>() { 
     public Void call() throws InterruptedException { 
      System.out.println(id + " started"); 
      Thread.sleep(1000); 
      System.out.println(id + " finished"); 
      return null; 
     } 
    }); 
} 

Prints

0 started 
1 started 
2 started 
3 started 
0 finished 
4 started 
1 finished 
5 started 
2 finished 
6 started 
3 finished 
7 started 
4 finished 
8 started 
5 finished 
6 finished 
9 started 
7 finished 
8 finished 
9 finished 
+0

Oui, ils sont parallèles - mais je suppose qu'il demande pourquoi, s'il crée des centaines de threads, aucun ne finit pendant la boucle principale. – sje397

+0

J'ai posté une mise à jour, jetez un oeil, s'il vous plaît. – Mick

+0

Vous démarrez les threads aussi vite que vous le pouvez, il n'y a pas de délai.Chaque thread prend beaucoup plus de temps à s'exécuter, alors ils commencent tous avant que le premier ne se termine. –

2

semble correct. Vous pouvez voir à partir de votre sortie que les threads sont entrelacés. les threads démarrent, basculent dans le contexte et sont sélectionnés par le planificateur, vous pouvez voir où le thread 8 passe devant le thread 5, par exemple. Si tous les chiffres étaient en ordre, ce serait étrange, mais cela semble bien.

Utilisez le temps de sommeil, comme le suggère Peter Lawrey, afin de pouvoir modifier la durée de chaque thread. Comme votre exemple l'indique, démarrer un processus prend tellement de temps qu'il semble raisonnable que tous vos threads commencent avant toute fin.

1

Si vous mettez une simple boucle à compter de 1 à 20 dans la méthode run(), vous pouvez voir l'entrelacement de l'exécution mieux.

1

Si vous voulez voir un début et de fin, vous pouvez ajouter un

« aléatoire » ou similaire aux fils.

Questions connexes