Un programme est souvent conçu comme une suite (séquentielle) d'instructions. Néanmoins, il est possible de concevoir des programmes où plusieurs tâches se déroulent simultanément, en parallèle ; ces différentes tâches portent le nom de threads et on dit alors que l'application est multithread. Ce parallélisme ne pourra être effectif que si la machine utilisée est multi-processeurs ; si ce n'est pas le cas, les différentes tâches se partagent successivement le processeur ; nous supposerons dans ce chapitre que la machine utilisée est mono-processeur. Pour obtenir des applications multithread, on démarre, en général avec une méthode main, un premier thread qui peut en lancer d'autres sans s'interrompre pour autant ; les nouveaux threads peuvent à leur tour démarrer d'autres threads. Un thread est quelquefois aussi appelé processus léger ou file d'exécution. Un programme multi-thread, est aussi dit concurrent.
Faire tourner plusieurs threads est simple. Mais, lorsque l'application est multithread, il faut souvent synchroniser les accès aux données partagées de façon à conserver leur cohérence, ce qui demande plus de soin. Par ailleurs, les différents threads doivent pouvoir se coordonner, s'attendre, s'alterner, être interrompus définitivement, être interrompus provisoirement et alors éventuellement être repris, etc. Ce sont ces différentes questions que nous traitons dans cette section.
Les threads sont munis d'un niveau de priorité. La méthode main est lancée avec une priorité moyenne. À sa création, un thread possède par défaut la même priorité que le thread qui lui a donné naissance. Le niveau de priorité peut être changé avec l'instruction appropriée. On peut espérer qu'un thread de priorité maximum s'exécutera et que tous les threads ayant cette priorité maximum bénéficieront du processeur. Les threads de priorité inférieure n'ont la garantie de s'exécuter que lorsque les threads de priorités supérieures sont bloqués ou finis. Lorsqu'un thread se bloque, Java exécute en principe (mais cela n'est pas toujours vérifié) l'un des threads non bloqués ayant la plus haute priorité. Entre des threads de même priorité, il n'y a pas de règle stricte sur le partage du processeur. Néanmoins, les machines peuvent se comporter de façons différentes et les exécutions sur une même machine peuvent varier d'une fois à l'autre. Aucune coordination fiable entre les threads ne peut être fondée uniquement sur les priorités.
Vous pouvez faire quelques exercices :
©Irène Charon, Télécom ParisTech 2011