Maison  >  Article  >  Java  >  C'est certainement l'explication la plus détaillée du multithreading Java

C'est certainement l'explication la plus détaillée du multithreading Java

无忌哥哥
无忌哥哥original
2018-07-20 11:49:382486parcourir

Multi-threading en 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.

Statut du thread

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.

Implémentation du thread (classe Tread et interface Runnable)

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();

Contrôle de base des threads

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)

Classification des threads

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)方法设定守护线程

Planification des threads

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

Problèmes existants

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

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;
        }
}

Autres problèmes

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.

API de concurrence (java.util.concurrent)

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn