Multithread 1.22

Multithreading:

Le multithreading fait référence à l'inclusion de plusieurs flux d'exécution dans le programme, ce qui signifie que plusieurs threads différents sont exécutés en même temps dans un programme pour effectuer différentes tâches

Threads et processus:

Processus: unité de base de l'allocation des ressources système. Une application exécutée en mémoire

Thread: L'unité de planification et d'exécution du processeur. Une tâche d'exécution dans le processus

Les threads du même processus partagent l'espace d'adressage et les ressources du processus

L'espace d'adressage et les ressources entre chaque processus sont indépendants les uns des autres

Un processus plante et n'affectera pas les autres threads en mode protégé

Un thread plante et tout le processus meurt

Trois éléments de la programmation simultanée: atomicité , visibilité et ordre

Fil utilisateur et fil démon:

Fil utilisateur: exécutez au premier plan, effectuez des tâches spécifiques.

Thread démon: s'exécute en arrière-plan, servant les threads des utilisateurs.

La fonction principale est un thread utilisateur. Lorsque la fonction principale est démarrée, la JVM démarre également de nombreux threads démons, tels que les threads de garbage collection.

Lorsque le thread utilisateur se termine, la JVM se ferme, qu'il y ait ou non un thread démon.

package com.zql.demo02;

public class TestDeamon {
    
    

    public static void main(String[] args) {
    
    
        //创建守护线程
        God god = new God();
        Thread thread = new Thread(god);
        //设置为守护线程
        thread.setDaemon(true);
        thread.start();
        //创建用户线程
        You you = new You();
        new Thread(you).start();
    }
}

//守护线程
class God implements Runnable{
    
    

    @Override
    public void run() {
    
    
        while (true){
    
    
            System.out.println("上帝守护你");
        }
    }
}

//用户线程
class You implements Runnable{
    
    

    @Override
    public void run() {
    
    
        for (int i = 0; i < 100; i++) {
    
    
            System.out.println("活了" + i + "年");
        }
    }
}

Thread deadlock:

Le blocage fait référence au phénomène de blocage de deux ou plusieurs processus (threads) dans le processus d'exécution en raison de la concurrence pour les ressources ou la communication.

Quatre conditions nécessaires à l'impasse:

1. Conditions mutuellement exclusives: les threads (processus) sont exclusifs aux ressources allouées, une ressource ne peut être occupée que par un thread (processus)

2. Conditions de demande et de conservation: Lorsqu'un thread (processus) est bloqué parce que la ressource demandée est occupée, conservez les ressources acquises

3. Conditions de non-privation: les ressources que le thread (processus) a acquises ne peuvent pas être privées de force par d'autres threads avant d'être utilisées.

4. Condition d'attente de boucle: Lorsqu'un blocage se produit, le thread en attente (processus) forme une boucle, semblable à une boucle infinie, provoquant un blocage permanent

Comment éviter les impasses:

Détruisez l'une des quatre conditions nécessaires

Créer un fil:

1. Hériter de la classe Thread

1. Créez une sous-classe Thread pour implémenter la classe Thread

2. Réécrivez la méthode d'exécution

3. Créez un objet thread, démarrez le thread

package com.zql.demo02;

public class TestThread extends Thread {
    
    

    @Override
    public void run() {
    
    
        System.out.println("run正在执行");
    }

    public static void main(String[] args) {
    
    
        TestThread testThread = new TestThread();
        testThread.start();
        System.out.println("main正在执行");
    }
}

2. Implémentez l'interface Runnable

1. Définissez la classe pour implémenter l'interface Runnable et remplacez la méthode run

2. Créez un objet thread

3. Jetez dans l'objet thread, démarrez le thread

package com.zql.demo02;

public class TestRunnable implements Runnable {
    
    
    @Override
    public void run() {
    
    
        System.out.println("run正在执行");
    }

    public static void main(String[] args) {
    
    
        TestRunnable testRunnable = new TestRunnable();
        new Thread(testRunnable).start();
        System.out.println("main正在执行");
    }
}

3. Implémentez l'interface Callable

1. Créez une classe d'implémentation pour implémenter l'interface Callable et définir le type de valeur de retour

2.new FutureTask crée un objet thread

3. Jetez dans l'objet thread, appelez start () pour démarrer le thread

package com.zql.demo02;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class TestCallable implements Callable<Integer> {
    
    
    @Override
    public Integer call() throws Exception {
    
    
        System.out.println("call执行");
        return 1;
    }

    public static void main(String[] args) throws InterruptedException, ExecutionException {
    
    
        FutureTask<Integer> integerFutureTask = new FutureTask<>(new TestCallable());
        new Thread(integerFutureTask).start();

        Thread.sleep(1000);
        System.out.println("获得返回值:" + integerFutureTask.get());

        System.out.println("main执行");
    }
}

La différence entre Runnable et Callable:

Similitudes:

1. Tous sont des interfaces

2. Les deux peuvent écrire des programmes multi-threads

3. Tout commence par start ()

Différence:

1. La méthode d'exécution de l'interface exécutable n'a pas de valeur de retour, la méthode d'appel d'interface appelable a une valeur de retour, c'est un générique

2. La méthode run de l'interface Runnable ne peut lever que des exceptions d'exécution et ne peut pas être interceptée; la méthode call de l'interface Callable peut lever des exceptions

L'interface Callable prend en charge le renvoi du résultat de l'exécution, qui doit être obtenu en appelant FutureTask.get (). Cette méthode empêchera le programme principal de s'exécuter

Quelle est la différence entre run () et start ():

Start () est utilisé pour démarrer le thread, run () est juste une fonction

Start () ne peut être appelé qu'une seule fois, run () peut être appelé d'innombrables fois

Appelez start () pour démarrer le thread, qui réalise vraiment une opération multithread.

Appelez directement run (), ce qui équivaut à appeler une fonction ordinaire

La méthode run () sera exécutée lorsque la méthode start () sera appelée, pourquoi ne pas appeler la méthode run () directement?

Un nouveau thread, le thread est dans un nouvel état. Appelez la méthode start () pour démarrer le thread et faire passer le thread dans l'état prêt, et il peut s'exécuter lorsque le processeur alloue une tranche de temps. Run () est appelé automatiquement.

L'appel direct de run () signifie que run () est exécuté comme une méthode ordinaire et non multithread.

L'appel de start () fera entrer le thread dans l'état prêt, l'appel de run () n'est qu'une méthode courante dans le thread.

Méthodes courantes:

1. Arrêtez le thread via l'indicateur externe .stop ()

package com.zql.demo02;

public class TestStop implements Runnable {
    
    

    //1.设置一个外部标识位
    private boolean flag = true;

    @Override
    public void run() {
    
    
        int j = 0;
        System.out.println("run执行---" + j++);
    }

    //2.设置一个停止方法
    public void stop(){
    
    
        this.flag = false;
    }

    public static void main(String[] args) {
    
    

        //3.创建线程对象
        TestStop testStop = new TestStop();
        //4.开启线程
        new Thread(testStop).start();
        //5.在规定下停止线程
        for (int i = 0; i < 50; i++) {
    
    
            System.out.println("main执行---" + i);
            if (i == 30){
    
    
                testStop.stop();
                System.out.println("线程停止");
            }
        }

    }
}

2. Compte à rebours de la simulation de sommeil de thread

package com.zql.demo02;

public class TestSleep {
    
    

    public static void main(String[] args) {
    
    
        try {
    
    
            tenDown();
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
    }


    public static void tenDown() throws InterruptedException {
    
    
        int num = 10;
        while (true){
    
    
            Thread.sleep(1000);
            System.out.println(num--);
            if (num <= 0){
    
    
                break;
            }
        }
    }
}

3. Rendement de filetage poli ()

La politesse peut ne pas réussir, selon la planification du processeur

package com.zql.demo02;

public class TestYield implements Runnable {
    
    
    @Override
    public void run() {
    
    
        System.out.println(Thread.currentThread().getName() + "---线程开始");
        Thread.yield();
        System.out.println(Thread.currentThread().getName() + "---线程开始");
    }

    public static void main(String[] args) {
    
    
        TestYield testYield = new TestYield();
        new Thread(testYield,"thread1").start();
        new Thread(testYield,"thread2").start();
    }
}

4. Appliquer la jointure ()

package com.zql.demo02;

public class TestJoin implements Runnable {
    
    
    @Override
    public void run() {
    
    
        for (int i = 0; i < 100; i++) {
    
    
            System.out.println("run线程---" + i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
    
    
        TestJoin testJoin = new TestJoin();
        Thread thread = new Thread(testJoin);
        thread.start();

        for (int i = 0; i < 100; i++) {
    
    
            if (i == 30){
    
    
                thread.join();
            }
            System.out.println("main线程---" + i);
        }
    }
}

Pool de threads:

Le pool de threads consiste à créer plusieurs threads exécutables à l'avance et à les placer dans un conteneur, à les extraire du conteneur en cas de besoin et à ne pas avoir besoin de les détruire après utilisation, réduisant ainsi la surcharge de création et de destruction d'objets.

Utilisez la classe d'outils Executors pour générer des pools de threads couramment utilisés:

1.newSingleThreadExecutor crée un pool de threads à thread unique

2.newFixedThreadPool crée un pool de threads de taille fixe

3.newCachedThreadPool crée un pool de threads pouvant être mis en cache

4.newScheduledThreadPool crée un pool de threads de taille illimitée

package com.zql.demo02;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestPool implements Runnable {
    
    
    @Override
    public void run() {
    
    
        System.out.println(Thread.currentThread().getName());
    }

    public static void main(String[] args) {
    
    
        //创建线程池    参数为线程池大小
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        executorService.execute(new TestPool());
        executorService.execute(new TestPool());
        executorService.execute(new TestPool());
        executorService.execute(new TestPool());

        //关闭连接
        executorService.shutdown();
    }
}

Je suppose que tu aimes

Origine blog.csdn.net/weixin_50960900/article/details/112983221
conseillé
Classement