Un article reconnaît 4 façons de créer du multithreading Java

Qu'est-ce qu'un programme?

  • Programme: Un ensemble d'instructions écrites dans une certaine langue pour accomplir une tâche spécifique. Fait référence à un code statique .

Qu'est-ce qu'un processus?

  • Processus: processus d'exécution d' un programme ou d' un programme en cours d'exécution.
  • Remarque: le processus est l'unité d'allocation des ressources et le système alloue différentes zones de mémoire pour chaque processus lorsque le système est en cours d'exécution.

Qu'est-ce qu'un fil?

  • Thread: Un processus peut être affiné en un thread , qui est un chemin d'exécution dans un programme.
  • Remarque: Les unités d'exécution sont l'unité de planification et d'exécution. Chaque unité d'exécution a une pile et un compteur de programme (pc) en cours d'exécution indépendants, et la surcharge de commutation des unités d'exécution est faible.

Parallèle et simultané:

  • Parallèle: plusieurs processeurs effectuent plusieurs tâches simultanément. Par exemple: plusieurs personnes font des choses différentes en même temps.

  • Concurrence: un processeur (à l'aide de tranches de temps) exécute plusieurs tâches simultanément. Lorsqu'il y a plusieurs threads en fonctionnement, si le système n'a qu'un seul processeur, il est impossible d'effectuer réellement plus d'un thread en même temps, il ne peut que diviser le temps d'exécution du processeur en plusieurs périodes, puis allouer la période à chaque thread Exécution, lorsque le code de thread s'exécute pendant un certain temps, les autres threads sont suspendus. C'est la simultanéité

Puis implémentation JAVA multi-thread:

Il existe trois façons principales de réaliser le multithreading JAVA: hériter de la classe Thread, implémenter l'interface Runnable, utiliser ExecutorService, Callable et Future pour réaliser le multithreading qui renvoie des résultats. Il n'y a pas de valeur de retour après les deux premières méthodes d'exécution de thread, seule la dernière a une valeur de retour.

(1) Héritez de la classe Thread pour obtenir plusieurs threads:

  • Bien que la méthode d'héritage de la classe Thread soit répertoriée en tant que méthode d'implémentation multithread, Thread est essentiellement une instance de l'interface Runnable, qui représente une instance d'un thread, et la seule façon de démarrer le thread est via le début de la classe Thread () Exemple de méthode. La méthode start () est une méthode native qui démarrera un nouveau thread et exécutera la méthode run (). Il est très simple d'implémenter le multithread de cette façon. Vous pouvez directement étendre Thread à travers votre propre classe et écraser la méthode run () pour démarrer un nouveau thread et exécuter votre propre méthode run ().
  1. Créer une sous-classe héritée de la classe Thread
  2. Réécrivez le run () de la classe Thread-> déclarez l'opération effectuée par ce thread dans run ()
  3. Créer un objet d'une sous-classe de la classe Thread
  4. ** Appelez start () via cet objet **
public class ThreadTest extends Thread{ //创建一个继承于Thread类的子类

    //重写Thread类的run() --> 将此线程执行的操作声明在run()中
    @Override
    public void run(){
        System.out.println("这是:[" + getName() + "]的启动");
    }
    
    public static void main(String[] args) {
        //创建Thread类的子类的对象
        ThreadTest thread1 = new ThreadTest();
        ThreadTest thread2 = new ThreadTest();
        thread1.setName("线程一");//给线程设置名字
        thread2.setName("线程二");
        thread1.start();//通过线程子类对象调用start()
        thread2.start();
    }

}

Résultat de la console:

这是:[线程一]的启动。
这是:[线程二]的启动。
Process finished with exit code 0
可知启动了两个线程

(2) Implémentez l'interface Runnable pour réaliser le multithread:

  • Si votre propre classe a déjà étendu une autre classe, vous ne pouvez pas étendre directement Thread. Dans ce cas, vous devez implémenter une interface Runnable:
  1. Créer une classe qui implémente l'interface Runnable

  2. Classe d'implémentation pour implémenter la méthode abstraite dans Runnable: run ()

  3. Créer un objet qui implémente la classe

  4. Passez cet objet en tant que paramètre au constructeur de la classe Thread pour créer un objet de la classe Thread

  5. Appelez start () via un objet de classe Thread

//创建一个实现了Runnable接口的类
public class RunnableStart extends Thread implements Runnable {
    
    //实现类去实现Runnable中的抽象方法:run()
    @Override
    public void run() {
        System.out.println("这是:[" + Thread.currentThread().getName() + "]的启动");
    }

    public static void main(String[] args) {
//        创建实现类的对象
        RunnableStart runnableThread = new RunnableStart();
//        将实现类对象作为参数传递到Thread类的构造器中,创建Thread类的对象
        Thread thread1 = new Thread(runnableThread);
        Thread thread2 = new Thread(runnableThread);
        thread1.setName("Runnable方式线程一:");//设置线程的名字
        thread2.setName("Runnable方式线程二:");
//        通过Thread类的对象调用start()
        thread1.start();
        thread2.start();
    }
}

La sortie console:

这是:[Runnable方式线程二:]的启动
这是:[Runnable方式线程一:]的启动
Process finished with exit code 0

** Remarque: ** En fait, lorsqu'un paramètre cible Runnable est transmis à Thread, la méthode run () de Thread appellera target.run (), reportez-vous au code source JDK:

public void run() {
  if (target != null) {
   target.run();
  }
}

(3) Implémenter la méthode appelable: (plus puissant que l'implémentation de la méthode Runnable)

Comment comprendre que la façon de créer un multi-thread en implémentant l'interface Callable est plus puissante que la façon de créer un multi-thread en implémentant l'interface Runnable?

  • call () peut avoir une valeur de retour.
  • call () peut lever une exception et être intercepté par une opération extérieure pour obtenir les informations d'exception
  • Callable prend en charge les génériques
  1. Créer une classe d'implémentation qui implémente Callable
  2. Implémentez la méthode d'appel et déclarez l'opération que ce thread doit effectuer dans call ()
  3. Créer un objet de classe d'implémentation d'interface appelable
  4. Passez l'objet de cette classe d'implémentation d'interface Callable au constructeur FutureTask pour créer un objet FutureTask
  5. Passez l'objet FutureTask en tant que paramètre au constructeur de la classe Thread, créez un objet Thread et appelez start ()
  6. Récupère la valeur de retour de la méthode d'appel dans Callable
//1.创建一个实现Callable的实现类
class CallThread implements Callable {
    //2.实现call方法,将此线程需要执行的操作声明在call()中
    @Override
    public Object call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
            if (i % 2 == 0) {
                sum += i;//计算100以内偶数之和
            }
        }
        return sum;
    }
}
public class ThreadTest {
    public static void main(String[] args) throws Exception {
        //3.创建Callable接口实现类的对象
        CallThread callThread = new CallThread();
        //4.将此Callable接口实现类的对象作为传递到FutureTask构造器中,创建FutureTask的对象
        FutureTask futureTask = new FutureTask(callThread);
        //5.将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start()
        Thread thread = new Thread(futureTask);
        thread.start();
        //6.获取Callable中call方法的返回值
        //get()返回值即为FutureTask构造器参数Callable实现类重写的call()的返回值。
        Object sum = futureTask.get();
        System.out.println("实现Callable方式的返回值总和为:" + sum);
    }
}

Résultat de la console:

实现Callable方式的返回值总和为:2550
Process finished with exit code 0

(4) Utilisez ExecutorService, Future (pool de threads): pour obtenir des résultats de retour multithread:

Méthode:

  1. Créer un pool de threads
  2. Créer plusieurs tâches avec des valeurs de retour
  3. Effectuer des tâches et obtenir des objets Future
  4. Fermer le pool de threads
public class ThreadPoolTest {
    public static void main(String[] args) throws Exception {
        System.out.println("----程序开始运行----");
        Date start = new Date();//开始时间
        // 创建一个指定数量的线程池
        ExecutorService pool = Executors.newFixedThreadPool(10);
        // 创建多个有返回值的任务
        List<Future> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {//因为只设有限定10个线程
            Callable call = new TestCallable(i + " ");
            // 执行任务并获取Future对象
            Future f = pool.submit(call);
            list.add(f);
        }
        // 关闭线程池
        pool.shutdown();
        // 获取所有并发任务的运行结果
        for (Future f : list) {
            // 从Future对象上获取任务的返回值,并输出到控制台
            System.out.println(">>>" + f.get().toString());
        }
        Date end = new Date();//结束时间
        System.out.println("----程序结束运行----,程序运行时间【"
                + (end.getTime() - start.getTime()) + "毫秒】");//计算出来的总运行时间
    }
}

class TestCallable implements Callable<Object> {
    private String taskNum;//任务编号

    TestCallable(String taskNum) {
        this.taskNum = taskNum;
    }

    @Override
    public Object call() throws Exception {
        System.out.println(">>>" + taskNum + "任务启动");
        Date dateStart = new Date();//开始时间
        Thread.sleep(1000);//阻塞1000毫秒
        Date dateEnd = new Date();//结束时间
        long time = dateEnd.getTime() - dateStart.getTime();
        System.out.println(">>>" + taskNum + "任务终止");
        return taskNum + "任务返回运行结果,当前任务时间【" + time + "毫秒】";
    }
}

Résultat de la console:

----程序开始运行----
>>>0 任务启动
>>>3 任务启动
>>>2 任务启动
>>>1 任务启动
>>>4 任务启动
>>>5 任务启动
>>>6 任务启动
>>>8 任务启动
>>>7 任务启动
>>>9 任务启动
>>>4 任务终止
>>>2 任务终止
>>>1 任务终止
>>>3 任务终止
>>>5 任务终止
>>>0 任务终止
>>>0 任务返回运行结果,当前任务时间【1001毫秒】
>>>1 任务返回运行结果,当前任务时间【1001毫秒】
>>>2 任务返回运行结果,当前任务时间【1001毫秒】
>>>3 任务返回运行结果,当前任务时间【1001毫秒】
>>>4 任务返回运行结果,当前任务时间【1001毫秒】
>>>5 任务返回运行结果,当前任务时间【1001毫秒】
>>>8 任务终止
>>>6 任务终止
>>>7 任务终止
>>>6 任务返回运行结果,当前任务时间【1001毫秒】
>>>7 任务返回运行结果,当前任务时间【1001毫秒】
>>>9 任务终止
>>>8 任务返回运行结果,当前任务时间【1001毫秒】
>>>9 任务返回运行结果,当前任务时间【1001毫秒】
----程序结束运行----,程序运行时间【1005毫秒】

Description du code du mode de pool de threads:

Code explication de l'auteur: wb_qiuquan.ying inexplicable vu aujourd'hui.

La classe Executors du code ci-dessus fournit une série de méthodes d'usine pour créer un pool de threads. Les pools de threads renvoyés implémentent tous l'interface ExecutorService.
public static ExecutorService newFixedThreadPool (int nThreads)
crée un pool de threads avec un nombre fixe de threads.
public static ExecutorService newCachedThreadPool ()
crée un pool de threads pouvant être mis en cache et l'appel de execute réutilisera le thread précédemment construit (si un thread est disponible). Si aucun thread existant n'est disponible, un nouveau thread est créé et ajouté au pool. Arrêtez et supprimez les threads qui n'ont pas été utilisés pendant 60 secondes.
public static ExecutorService newSingleThreadExecutor ()
crée un exécuteur monothread .
public static ScheduledExecutorService newScheduledThreadPool (int corePoolSize)
crée un pool de threads qui prend en charge l'exécution de tâches planifiées et périodiques et peut être utilisé pour remplacer la classe Timer dans la plupart des cas.

ExecutoreService fournit une méthode submit (), transmettant un appelable ou exécutable et renvoyant Future. Si le pool de threads d'arrière-plan Executor n'a pas terminé le calcul de Callable, cet appel renvoie la méthode get () de l'objet Future, qui se bloquera jusqu'à la fin du calcul.


Résumé: Il s'agit de la création de 4 types de threads et d'une brève introduction aux threads. Si vous avez d'autres questions, veuillez me contacter.

Numéro public de l'auteur: codage Xiaobai, tout le monde est invité à faire attention à étudier ensemble.

Insérez la description de l'image ici

A publié 13 articles originaux · gagné 41 · vues 820

Je suppose que tu aimes

Origine blog.csdn.net/weixin_46146269/article/details/105613082
conseillé
Classement