Le langage Java, depuis ses toutes premières versions, supporte l'exécution de différents codes de calcul dans différents fils d'exécution. Un fil d'exécution est appelé un
thread
dans le jargon de l'informatique en général, et c'est ce terme que nous utiliserons dans la suite.
Exécuter plusieurs codes différents dans plusieurs threads donne l'impression que chaque code s'exécute en parallèle des autres, et donne l'apparence de la simultanéité. Au même moment, plusieurs instructions sont exécutées. Cette apparente simultanéité peut être trompeuse, et il se peut que le temps CPU soit en fait découpé en tranches temporelles, distribuées par la machine Java aux différents fils d'exécution. Dans ce cas la simultanéité n'existe pas, et ce mode de fonctionnement a été la règle durant des années.
Aujourd'hui les architectures multiprocesseurs et multicœurs sont devenues la norme. Même les processeurs les plus légers ont plusieurs cœurs, n'importe quel ordinateur de bureau récent a toutes les chances d'en être équipé.
L'expansion inéluctable de ces architectures à plusieurs CPU met les problématiques de la programmation concurrente au centre des préoccupations de tout développeur Java. L'objet de ce cours est de présenter les grandes notions sur lesquelles ces problématiques se fondent, ainsi que les principaux patterns d'utilisation.
L'API Java Concurrent a subi d'importants ajouts en version 5, qui sont couverts dans ce cours.