Maison >Java >javaDidacticiel >C'est certainement l'explication la plus détaillée du multithreading Java
Dans les processus et threads précédents du système d'exploitation, les threads ont été expliqués en détail sur l'implémentation des threads, cet article en donnera quelques-unes. plus d'introduction.
Pour l'état du thread en Java, nous pouvons utiliser un modèle à cinq états pour le représenter, qui sont :
Créer, prêt, exécuter, bloqué, terminer cinq états
État de création : JVM appelle la méthode main() pour créer un thread principal. Le thread principal démarre un thread enfant en appelant la méthode start() de l'objet thread. état de création. Lorsque le thread exécute divers Une fois les conditions remplies, entrez dans la file d'attente prête.
Pour les autres états divers, veuillez vous référer aux explications dans les processus et les discussions.
Il existe deux façons de créer un thread en Java, à savoir en héritant de la classe Thread et en implémentant l'interface Runnable. L'introduction spécifique est la suivante :
Le multi-threading peut être implémenté en Java via la classe Thread et ses sous-classes et l'interface Runnable.
La classe Thread peut définir directement des objets thread, mais il est généralement nécessaire de définir une sous-classe de la classe Thread pour implémenter le multi-threading afin de répondre aux exigences particulières de la programmation. Limitées par l'héritage unique de Java, dans les applications pratiques, presque toutes les applications multithread implémentent le multithread en implémentant l'interface exécutable.
En d'autres termes, si la classe nouvellement créée souhaite hériter d'autres classes, car l'héritage multiple n'est pas pris en charge en Java, les tâches multithread ne peuvent être effectuées qu'en implémentant l'interface java.lang.Runnable. adaptés à plusieurs codes de programme identiques. Les threads sont utilisés pour traiter la même ressource, séparant efficacement le processeur virtuel (thread) du code et des données du programme.
Les codes pour l'implémentation des deux threads sont les suivants :
public class ThreadDemo extends Thread { int i = 0; public void run(){ while (i<10){ System.out.println("实现Thread类继承的线程,正在占有处理机运行……"+i); try{ sleep(1000); i++; }catch (InterruptedException e){ e.printStackTrace(); } } } }
Dans la fonction main, il suffit d'instancier la classe et d'appeler la méthode start() pour créer un fil de discussion.
public class RunnableDemo implements Runnable { int i = 0; @Override public void run(){ while (i<10) { System.out.println("实现Runnable接口的线程,正在占有处理机运行……" + i); try { Thread.sleep(1000); i++; } catch (InterruptedException e) { e.printStackTrace(); } } } }
Méthode d'implémentation dans la fonction principale :
Thread thread = new Thread(RunnableDemo ); Thread.start();
Début du thread : thread.start()
Thread End : Définissez une variable mark pour terminer la boucle correspondante et la méthode
pour empêcher temporairement l'exécution du thread : Try{Thread.sleep(1000);}catch(InterruptedException e){ }
Définir la priorité du thread : méthode setPriority(int priorité)
Max_priority La priorité la plus élevée qu'un thread peut avoir (généralement 10)
Min_priority La priorité la plus élevée qu'un thread peut avoir (généralement 1)
Normal_priority La priorité par défaut attribuée au thread (généralement 5)
Il existe deux types de threads en Java : User Thread (thread utilisateur) et Daemon Thread (démon thread), le rôle du thread démon est de fournir des services pour l'exécution d'autres threads, tels que les threads de garbage collection. Dans un programme Java, s'il y a des threads non-démon, le programme entier ne se terminera pas.
通过setDaemon(true)方法设定守护线程
Jvm est responsable de l'allocation du processeur aux threads, ce que l'on appelle la planification des threads. Le principe est le suivant : les threads de haute priorité s'exécutent en premier avec égalité. priorité. Les threads allouent directement les ressources CPU en fonction de la rotation des tranches de temps
Incertitude des threads : Une simple instruction en Java correspond à plusieurs instructions dans le CPU lorsqu'un thread juste après une instruction. est exécuté et planifié, les threads suivants appellent à plusieurs reprises les données d'origine, ce qui entraîne une incertitude du thread (non atomique)
Synchronisation des threads : s'exécute simultanément Si les threads doivent partager des données, ils doivent Tenez compte de l'état et du comportement des autres threads. À l'heure actuelle, la synchronisation doit être implémentée. Java introduit le concept de verrous mutex d'objet pour garantir l'intégrité des opérations de données partagées. Chaque objet correspond à un moniteur (monitor), qui porte une marque appelée "verrou mutex (lock, mutex)". Cette marque est utilisée pour garantir qu'un seul thread peut accéder à l'objet à tout moment. Le mot-clé synchronisé permet de contacter le verrou mutex de l'objet
Utilisation de synchronisé :
Pour fragment de code synchronisé (objet) {}
Pour une méthode : synchronisé Dans la déclaration de méthode, Public synchronisé void push (char c) {} équivaut à synchronisé (this), indiquant que la méthode entière est une méthode synchronisée
Contrôle de synchronisation des threads :
Vous pouvez utiliser la méthode wait() Libérez le verrou de l'objet
Utilisez notify() ou notifyAll() pour faire passer un ou tous les threads en attente à l'état prêt
En Java, wait et notify peuvent être placés dans synchronisé, pendant l'exécution synchronisée Lorsqu'un thread appelle la méthode d'attente d'un objet, il libère l'identifiant de verrouillage de l'objet puis entre dans l'état d'attente. Ensuite, d'autres threads appellent la méthode notify() ou notify() pour notifier le thread en attente.
Le code spécifique est le suivant :
class CubbyHole { private int index = 0; private int[] data = new int[3]; public synchronized void put(int value){ while (index == data.length){ try{ this.wait(); }catch (InterruptedException e){ e.printStackTrace(); } } data[index++] = value; this.notify(); } public synchronized int get(){ while (index <=0) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } int value = data[index--]; this.notify(); return value; } }
Dans une synchronisation simple, le verrouillage et le déverrouillage peuvent facilement provoquer des problèmes de blocage, c'est-à-dire s'attendre l'un l'autre . Java a introduit quelques méthodes après la version 1.5 pour résoudre les problèmes de multi-threading.
Depuis JDK1.5, une série d'API plus utiles telles que des variables uniques, des collections, des minuteries et des pools de threads ont été fournies.
Variable atomique java.util.concurrent.atomic package Classe AtomicInteger
La méthode GetAndIncrement() garantit que l'accès aux threads est sécurisé
Classe de collection simultanée Java.util.concurrent Ajoutez-en classes CopyOnWriteArrayList et CopyOnWriteSet
au package, qui conviennent aux objets rarement écrits mais lus fréquemment
ConcurrentHashMap
Les producteurs et les consommateurs d'ArrayBlockingQueue utilisent put et get
Utiliser des pools de threads
Classe liée au pool de threads, interface ExecutorService, classe ThreadPoolExecutor, classe d'outils Executors
Utilisation courante ExecutorService pool = Executors .newCachedThreadPool();
Utiliser sa méthode execute(Runnable r)
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!