1. Créez un fil de discussion
Il existe deux manières de créer des threads en Java : en utilisant la classe Thread et en utilisant l'interface Runnable. Lorsque vous utilisez l'interface Runnable, vous devez créer une instance de Thread. Par conséquent, que vous créiez un thread via la classe Thread ou l'interface Runnable, vous devez créer une instance de la classe Thread ou de sa sous-classe. Constructeur de fil :
Méthode 1 : hériter de la classe Thread et remplacer la méthode run
}
}
la classe Demo étend Thread{
public void run(){
pour(int i=0;i<60;i++){
System.out.println(Thread.currentThread().getName()+i);
}
}
}
Tout comme les gens naissent, vieillissent, sont malades et meurent, les fils doivent également passer par quatre états différents : démarrer (attendre), courir, se suspendre et s'arrêter. Ces quatre états peuvent être contrôlés via des méthodes de la classe Thread. Les méthodes liées à ces quatre états dans la classe Thread sont indiquées ci-dessous.
Le thread n'exécute pas le code dans la méthode run immédiatement après son établissement, mais est dans un état d'attente. Lorsque le thread est en attente, vous pouvez définir divers attributs du thread via les méthodes de la classe Thread, tels que la priorité du thread (setPriority), le nom du thread (setName) et le type de thread (setDaemon).
Lorsque la méthode start est appelée, le thread commence à exécuter le code dans la méthode run. Le thread entre dans l'état d'exécution. Vous pouvez utiliser la méthode isAlive de la classe Thread pour déterminer si le thread est en cours d'exécution. Lorsque le thread est à l'état d'exécution, isAlive renvoie true. Lorsque isAlive renvoie false, le thread peut être à l'état d'attente ou à l'état arrêté. Le code suivant illustre la commutation entre les trois états de création de thread, d'exécution et d'arrêt, et génère la valeur de retour isAlive correspondante.
Une fois que le thread commence à exécuter la méthode run, il ne se terminera pas tant que la méthode run ne sera pas terminée. Cependant, lors de l'exécution du thread, deux méthodes peuvent être utilisées pour arrêter temporairement l'exécution du thread. Ces deux méthodes sont la suspension et la mise en veille. Après avoir utilisé suspend pour suspendre un thread, vous pouvez le réactiver via la méthode de reprise. Après avoir utilisé sleep pour mettre le thread en veille, le thread ne peut être dans l'état prêt qu'après le temps défini (une fois la veille du thread terminée, le thread peut ne pas s'exécuter immédiatement, mais entre uniquement dans l'état prêt, en attendant que le système planifie) .
Il y a deux points à noter lors de l’utilisation de la méthode sleep :
1. La méthode sleep a deux formes surchargées. L'une des formes surchargées peut non seulement définir des millisecondes, mais également des nanosecondes (1 000 000 nanosecondes équivaut à 1 milliseconde). Cependant, la machine virtuelle Java sur la plupart des plates-formes de système d'exploitation n'est pas précise en nanosecondes. Par conséquent, si les nanosecondes sont définies pour la veille, la machine virtuelle Java prendra la milliseconde la plus proche de cette valeur.
2. Throws ou try{...}catch{...} doivent être utilisés lors de l'utilisation de la méthode sleep. Étant donné que la méthode run ne peut pas utiliser de lancers, vous ne pouvez utiliser que try{...}catch{...}. Lorsque le thread est en veille et que la méthode d'interruption est utilisée pour interrompre le thread, sleep lèvera une InterruptedException. La méthode sleep est définie comme suit :
Il existe trois façons de terminer un thread.
1. Utilisez l'indicateur de sortie pour que le thread se termine normalement, c'est-à-dire que le thread se termine lorsque la méthode run est terminée.
2. Utilisez la méthode stop pour forcer l'arrêt du thread (cette méthode n'est pas recommandée car stop, comme la suspension et la reprise, peut également produire des résultats imprévisibles).
3. Utilisez la méthode d'interruption pour interrompre le thread.
1. Terminez le fil de discussion à l'aide de l'indicateur de sortie
Lorsque la méthode run est exécutée, le thread se ferme. Mais parfois, la méthode run ne se termine jamais. Par exemple, les threads sont utilisés dans les programmes serveur pour surveiller les demandes des clients ou d'autres tâches nécessitant un traitement cyclique. Dans ce cas, ces tâches sont généralement placées dans une boucle, comme une boucle while. Si vous souhaitez que la boucle s'exécute indéfiniment, vous pouvez utiliser while(true){...} pour la gérer. Mais si vous souhaitez que la boucle while se termine dans une certaine condition, le moyen le plus direct consiste à définir un indicateur de type booléen et à définir cet indicateur sur true ou false pour contrôler si la boucle while se termine. Un exemple de terminaison d’un thread à l’aide de l’indicateur de sortie est donné ci-dessous.
La fonction de la méthode join est de faire en sorte que les threads d'exécution asynchrones deviennent une exécution synchrone. C'est-à-dire que lorsque la méthode start de l'instance de thread est appelée, cette méthode sera immédiatement renvoyée. Si vous devez utiliser une valeur calculée par ce thread après avoir appelé la méthode start, vous devez utiliser la méthode join. Si vous n'utilisez pas la méthode join, rien ne garantit que lorsqu'une instruction suivant la méthode start est exécutée, le thread sera exécuté. Après avoir utilisé la méthode join, le programme ne poursuivra pas son exécution tant que ce thread ne se terminera pas. Le code suivant montre l'utilisation de join.
3. Problèmes de sécurité multithread
Cause du problème : lorsque plusieurs instructions fonctionnent sur le même thread et partagent des données, un thread n'exécute qu'une partie des multiples instructions. Avant la fin de l'exécution, un autre thread participe à l'exécution, ce qui entraîne des erreurs de données partagées.
Solution : pour plusieurs instructions fonctionnant sur des données partagées, un seul thread peut être exécuté pendant le processus d'exécution, les autres threads ne s'exécuteront pas.
Bloc de code synchrone :
}
}
}
}
public void run(){
tandis que(vrai){
saleTicket();
}
}
}
Communication entre les threads
x=(x+1)%2;
}
}
}).commencer();
nouveau fil de discussion (nouveau Runnable(){
public void run(){
tandis que(vrai){
p.get();
}
}
}).commencer();
}
}
/*
Zhang San....Homme Zhang San....Homme
lili....nv
lili...mâle Zhang San....nv
lili.... mâle
*/
}
}
}).commencer();
nouveau fil de discussion (nouveau Runnable(){
public void run(){
tandis que(vrai){
synchronisé (p) {
p.get();
}
}
}
}).commencer();
}
}
/*
lili....nv
lili....nv
lili....nv
lili....nv
lili....nv
lili....nv
Zhang San....Homme Zhang San....Homme Zhang San....Homme Zhang San....Homme
*/
}
}
}).commencer();
nouveau fil de discussion (nouveau Runnable(){
public void run(){
tandis que(vrai){
synchronisé (p) {
si(!drapeaux)
essayer {
p.wait();
} catch (InterruptedException e) {
// TODO Bloc catch généré automatiquement
e.printStackTrace();
} ;
p.get();
drapeaux = faux ;
p.notifyAll();
}
}
}
}).commencer();
}
}
}
Biens finaux g = biens nouveaux ();
nouveau fil de discussion (nouveau Runnable(){
public void run(){
tandis que(vrai){
g.produire("marchandises");
}
}
}).commencer();
nouveau fil de discussion (nouveau Runnable(){
public void run(){
tandis que(vrai){
g.consume();
}
}
}).commencer();
}
}
}
Biens finaux g = biens nouveaux ();
nouveau fil de discussion (nouveau Runnable(){
public void run(){
tandis que(vrai){
g.produire("marchandises");
}
}
},"Producteur n°1").start();
nouveau fil de discussion (nouveau Runnable(){
public void run(){
tandis que(vrai){
g.produire("marchandises");
}
}
},"Producteur n°2").start();
nouveau fil de discussion (nouveau Runnable(){
public void run(){
tandis que(vrai){
g.consume();
}
}
},"Consommateur n°1").start();
nouveau fil de discussion (nouveau Runnable(){
public void run(){
tandis que(vrai){
g.consume();
}
}
},"Consommateur n°2").start();
}
}
/*
Consommateur n°2 consommé ****** numéro de produit : 48049
Producteur Un produit....Numéro d'article : 48050
Consommateur n°1 consommé ****** numéro de produit : 48050
Producteur Un produit....Numéro d'article : 48051
Consommateur n°2 consommé ****** numéro de produit : 48051
Producteur n°2 produit....Numéro d'article : 48052
Consommateur n°2 consommé ****** numéro de produit : 48052
Producteur Un produit....Numéro d'article : 48053
Consommateur n°1 consommé ****** numéro de produit : 48053
Producteur Un produit....Numéro d'article : 48054
Consommateur n°2 consommé ****** numéro de produit : 48054
Producteur n°2 produit....Numéro d'article : 48055
Consommateur n°2 consommé ****** numéro de produit : 48055
*/