Maison  >  Article  >  Java  >  Comment comprendre les threads en Java

Comment comprendre les threads en Java

王林
王林avant
2023-04-29 22:01:051127parcourir

Comment comprendre les threads en Java

Thread est un chemin d'exécution à l'intérieur d'un programme. La méthode principale que nous connaissons est en fait un chemin d'exécution distinct. S'il n'y a qu'un seul chemin d'exécution dans le programme, alors Ce programme est un programme monothread ; puisqu'il existe un seul thread, il y aura également du multi-threading. Le sens littéral peut être compris comme « une technologie qui utilise plusieurs processus d'exécution sur des logiciels et du matériel par rapport à un seul. thread". Les avantages du multi-threading sont #🎜🎜 #Améliorer l'utilisation du processeur. Dans un programme multithread, lorsqu'un thread doit attendre, le processeur peut exécuter d'autres threads au lieu d'attendre, améliorant ainsi considérablement l'efficacité du programme.

Création de multi-threads

Méthode 1 : Hériter de la classe Thread

Processus de création de la méthode 1 :

#🎜 🎜 #
    Définir une sous-classe MyThread pour hériter de la classe de thread java.lang.Thread et remplacer la méthode run()
  • Créer un objet de MyThread ; class; #🎜 🎜#
  • Appelez la méthode start() de l'objet thread pour démarrer le thread (la méthode run() est toujours exécutée après le démarrage) ;
  • #🎜 🎜#Il y a deux threads qui s'exécutent dans le code ci-dessus, à savoir le thread principal de la méthode main et le sous-thread démarré en appelant start() sur l'objet thread mythread. Mais pourquoi le résultat de sortie n’est-il pas unique ? La raison en est que la préemption du processeur se produira entre les deux threads lors de l'exécution, et celui qui s'en emparera en premier s'exécutera en premier.

  • Alors pourquoi n'utilisons-nous pas directement l'objet thread pour appeler la méthode run() ? Si run() est appelé directement, il s'agit simplement d'une méthode d'appel normale, c'est-à-dire d'un seul thread, tandis que la méthode start() est utilisée pour démarrer les threads enfants, afin que le multithreading puisse se produire.

    Avantages et inconvénients de la première méthode :

Avantages : codage simple ; 🎜# Inconvénients : La classe thread a hérité de Thread et ne peut pas hériter d'autres classes, ce qui n'est pas propice à l'expansion ; Processus :

1 Définir une classe de tâches de thread MyRunnable pour implémenter l'interface Runnable et remplacer l'exécution. () méthode ;
  • 2. Créez un objet MyRunnable ;

    #🎜🎜 #3. Remettez l'objet de tâche MyRunnable à Thread pour traitement ; Appelez la méthode start() de l'objet thread pour démarrer le thread ;

  • public Thread (String name)

    peut être spécifié pour le fil de discussion actuel. Nom

public Thread (Runnable target)

Encapsuler l'objet Runnable pour devenir un objet thread

# 🎜🎜#public Thread (Runnable target, String name)#🎜 🎜#

Encapsulez l'objet Runnable en tant qu'objet thread et spécifiez le nom du thread

public class ThreadDemo01 {
    public static void main(String[] args) {
        MyThread myThread1 = new MyThread();
        myThread1.start();
        for (int i = 0; i < 3; i++) {
            System.out.println("主线程正在执行~~");
        }
    }
}
class MyThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            System.out.println("子线程正在执行~~");
        }

    }
}
//输出结果(不唯一):
//主线程正在执行~~
//主线程正在执行~~
//主线程正在执行~~
//子线程正在执行~~
//子线程正在执行~~
//子线程正在执行~~
#🎜 🎜#La différence entre ce code et la méthode 1 est que l'objet de tâche MyRunnable doit être encapsulé dans Thread. Les autres emplacements sont fondamentalement inchangés. Avantages et inconvénients de la deuxième méthode : Ensuite, nous utilisons également l'interface Runnable (formulaire de classe interne anonyme) pour réaliser la création de multi-threads : 2. Laissez-le à Thread pour le traitement ; 3. Appelez start() de l'objet thread pour démarrer le thread ; tandis que l'autre est multithread via des classes internes anonymes. Et ce bloc de code peut également être rationalisé grâce à des expressions lambda. Je me demande si vous êtes toujours impressionné par ce point de connaissance ? Si vous oubliez, vous pouvez lire cet article : Comment comprendre les expressions lambda en Java - simplificationMéthode 3 : Implémenter l'interface CallableAprès avoir appris les deux créations précédentes Après le Avec une approche multithread, nous constaterons qu'il y a un problème : 1. La méthode run() réécrite ne peut pas renvoyer directement les résultats ; 2. Elle ne convient pas aux scénarios métier qui doivent renvoyer les résultats de l'exécution du thread ; Nous avons donc besoin d’une troisième voie pour résoudre ces problèmes. Processus de création de la méthode trois : 1 Définir une classe pour implémenter l'interface Callable, remplacer la méthode call() et encapsuler ce qui doit être fait ; 🎜#5 Une fois l'exécution du thread terminée, obtenez le résultat de l'exécution de la tâche via la méthode get() de FutureTask. # 🎜🎜 ## 🎜🎜 ## 🎜🎜 ## 🎜🎜 ## 🎜🎜 # Nom de la méthode # 🎜🎜 ## 🎜🎜 # Description # 🎜🎜 ## 🎜🎜 ## 🎜🎜 ## 🎜🎜 # # public FutureTask & lt; >(Appel Callable)
Avantages : la classe de tâches de thread implémente uniquement l'interface, et peut continuer à hériter de la classe et à implémenter l'interface, et a une forte évolutivité ; Inconvénients : La programmation nécessite une couche supplémentaire d'empaquetage d'objets. Si le thread a des résultats d'exécution, il ne peut pas être renvoyé directement.
1 Créez un objet de classe interne anonyme Runnable #🎜. 🎜#
2. Utilisez FutureTask pour encapsuler l'objet Callable dans un objet de tâche de thread 3. Remettez l'objet de tâche de thread à Thread pour traitement ; 4. Appelez la méthode start() de Thread pour démarrer Thread, exécutez la tâche ;
Encapsuler l'objet Callable dans un objet FutureTask

public V get() lève une exception

# 🎜 🎜#Récupérer le résultat renvoyé par le thread exécutant la méthode d'appel

public class ThreadDemo03 {
    public static void main(String[] args) throws Exception {
        MyCallable myCallable = new MyCallable();
        FutureTask<String> futureTask = new FutureTask<>(myCallable);
        Thread thread = new Thread(futureTask);
        thread.start();
        int sum= 0;
        for (int i = 0; i < 3; i++) {
            sum+=i;
        }
        System.out.println(sum);
        String s =futureTask.get();
        System.out.println(s);
    }
}
class MyCallable implements Callable<String > {
    @Override
    public String call(){
        int sum=0;
        for (int i = 0; i < 3; i++) {
            sum+=i;
        }
        return "子线程计算结果:"+sum;
    }
}
//输出结果:
//3
//子线程计算结果:3

方式三优缺点:

优点:

线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强;

可以在线程执行完毕后去获取 线程执行的结果;

缺点:

编码复杂一点;

总结

方式 优点 缺点
继承Thread类 编程比较简单,可以直接使用Thread类中的方法 扩展性较差,不能再继承其他的类,不能返回线程执行的结果
实现Runnable接口 扩展性强,实现该接口的同时还可以继承其他的类 编程相对复杂,不能返回线程执行的结果
实现Callable接口 扩展性强,实现该接口的同时还可以继承其他的类,可以得到线程的执行结果 编程相对复杂

常用方法

Thread获取和设置线程名称

方法名称 说明
String getName() 获取当前线程的名称,默认线程名称是Thread-索引
void setName(String name)

将此线程更改为指定的名称,通过构造器也可以设置线程名称

简单地通过一段代码让大家能够清晰地了解这个代码该如何使用:

public class ThreadDemo04 {
    public static void main(String[] args) throws Exception {
        thread thread1 = new thread();
        thread1.setName("1号子线程");
        thread1.start();
        thread thread2 = new thread();
        thread2.setName("2号子线程");
        thread2.start();
    }
}
class thread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            System.out.println(this.getName()+"正在执行任务"+i);
        }
    }
}
//输出结果:
//2号子线程正在执行任务0
//1号子线程正在执行任务0
//2号子线程正在执行任务1
//1号子线程正在执行任务1
//2号子线程正在执行任务2
//1号子线程正在执行任务2

Thread类的线程休眠方法

方法名称 说明
public static void sleep(long time) 让当前线程休眠指定的时间后再继续执行,单位为毫秒
public class ThreadDemo05 {
    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 5; i++) {
            System.out.println(i);
            if (i==3){
                Thread.sleep(5000);
            }
        }
    }
}
//输出结果:
//1
//2
//3
//在输出过3以后,等待5秒之后再进行输出
//4

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer