Educoder/Touge JAVA——Fonctionnalités avancées de JAVA : Principes de base du multithreading (1) Utilisation des threads

Niveau 1 : création de threads

informations connexes

Je ne sais pas si vous avez remarqué, jusqu'à présent, les codes que nous écrivons sont tous exécutés dans la fonction de haut en basmain() dans l'ordre dans lequel le code est écrit .

Mais le logiciel que nous utilisons habituellement peut exécuter plusieurs tâches en même temps. Quel est le mécanisme de fonctionnement ? Dans cette section, nous allons discuter.

Qu'est-ce qu'un fil, qu'est-ce qu'un processus

Afin Javad'exécuter plusieurs tâches en même temps (s'il s'agit d'un seul cœur, pour être précis, il est exécuté en alternance), le multi-threading est utilisé. Pour comprendre les threads, nous devons d'abord comprendre ce qu'est un processus et ce qu'est un fil de discussion.

Définition générale : un processus fait référence à un programme d'application s'exécutant dans le système d'exploitation , et un thread fait référence à une unité qui exécute indépendamment une certaine tâche au sein d'un processus.

Par exemple, QQil s'agit d'un processus . Si vous Atapez et discutez avec des amis tout en discutant avec Bdes amis et QQque vous téléchargez des images dans le groupe en même temps, ces trois opérations équivalent à ouvrir trois fils . On peut dire qu'après avoir eu des fils , nous avons conçu Le programme peut effectuer Ades opérations tout en effectuant Bdes opérations.

Quelle est la différence entre thread et process ? Tout d'abord, la chose la plus intuitive est la suivante : un processus peut avoir plusieurs threads. Comparaison spécifique :

  • **Planification** Les processus possèdent leurs propres ressources ; les threads sont l'unité de base de la planification et de la répartition ; la commutation de threads dans le même processus n'entraînera pas de commutation de processus ; la commutation de threads entre processus entraînera une commutation de processus et donc une commutation de ressources, etc.

  • **Processus de simultanéité** : exécution simultanée entre les processus ; thread : en plus de l'exécution simultanée entre les processus, il peut également être exécuté simultanément entre les threads ; les threads ont une simultanéité plus élevée.

  • **Ressources propres** Les threads ne peuvent pas posséder de ressources, seuls les processus possèdent des ressources.

  • **Surcharge du système** La création, la commutation et l'annulation de processus obligeront le système à créer ou à récupérer des cartes de contrôle de processus et des ressources pour celui-ci, mais la création et la commutation de threads n'entraîneront pas le système à faire ces choses, donc la surcharge système des threads Significativement plus petit.

Comment créer des fils de discussion

Ici, nous maîtrisons principalement deux façons de créer des threads.

1. ThreadClasse d'héritage ;

Nous pouvons Threadcréer un thread en héritant de la classe. Créez une classe pour hériter Threadde la classe, réécrivez la méthode de la classe parent runet créez notre propre thread. Après avoir appelé startla méthode du thread, même si un thread est ouvert.

Exemple:

class MyThread extends Thread{
    private String name;
    public MyThread(String name) {
        super();
        this.name = name;
    }
    public void run() {
        System.out.println("线程" + name +"开始运行");
        for (int i = 0; i < 5; i++) {
            System.out.println("线程" +  name + "运行" + i);
        }
        System.out.println("线程" + name + "结束");
    }
}
public class Test {
    public static void main(String[] args) {
        Thread t = new MyThread("T!");
        t.start();
        Thread t2 = new MyThread("T2");
        t2.start();
    }
}
/*_________________________________*/
运行结果:
线程T!开始运行
线程T2开始运行
线程T!运行0
线程T2运行0
线程T!运行1
线程T2运行1
线程T!运行2
线程T!运行3
线程T!运行4
线程T2运行2
线程T2运行3
线程T2运行4
线程T2结束
线程T!结束

En exécutant ce code, nous constaterons que les threads s'exécutent alternativement et que la sortie de chaque exécution est différente et que la sortie est aléatoire.

2. Implémentez Runnablel'interface.

Le moyen le plus simple de créer un thread consiste à implémenter une Runnableinterface. En fait, tous les threads implémentent Runnablel'interface directement ou indirectement. Dans l'exemple précédent, Threadla classe implémente en fait Runnablel'interface.

Exemple:

class MyThread implements Runnable {
    private String name;
    private Thread mythread;
    public MyThread(String name) {
        super();
        this.name = name;
    }
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("线程" + name + "运行" + i);
        }
        System.out.println("线程" + name + "结束");
    }
    public void start() {
        System.out.println("线程开始: " + name);
        if (mythread == null) {
            mythread = new Thread(this, name);
            mythread.start();
        }
    }
}
public class Test {
    public static void main(String[] args) {
        MyThread t1 = new MyThread("T1");
        t1.start();
        MyThread t2 = new MyThread("T2");
        t2.start();
    }
}
/*____________________________________*/
运行结果:
线程开始: T1
线程开始: T2
线程T1运行0
线程T2运行0
线程T1运行1
线程T1运行2
线程T1运行3
线程T1运行4
线程T1结束
线程T2运行1
线程T2运行2
线程T2运行3
线程T2运行4
线程T2结束

Après Java1.5la version, il fournit également un moyen de créer des threads : créez des threads via Callable et Future , que nous apprendrons dans une formation ultérieure.

Comparaison de deux façons de créer des threads

  • Lors de la création Runnabled'un thread, la classe thread implémente uniquement Runnablel'interface et peut hériter d'autres classes.

  • Lors de l'héritage THreadd'une classe pour créer un thread, la classe de thread hérite Threadde la classe et ne peut pas hériter d'autres classes. Cependant, cette méthode est facile à écrire. Si vous avez besoin d'accéder au thread en cours, vous n'avez pas besoin d'utiliser Thread.currentThread() la méthode et vous thispouvez obtenir le thread en cours directement.

Le thread démarré par le programme java par défaut

Dans Java, au moins un thread est lancé à chaque exécution du programme 2. L'un est mainun thread et l'autre est un thread de récupération de place . Parce que Javachaque fois qu'une commande est utilisée pour exécuter une classe, une est en fait démarrée jvmet chacune jvmdémarre en fait un processus dans le système d'exploitation.

exigences de programmation

Begin - EndVeuillez lire attentivement le code sur la droite et compléter le code dans la zone en fonction des invites de la méthode . Les tâches spécifiques sont les suivantes :

  • ThreadCréez une classe ThreadClassOnenommée héritant de la classe, et la runméthode réécrite doit atteindre 0-10un nombre impair entre les sorties, et les résultats de sortie sont les suivants : 1 3 5 7 9;

  • Créez une classe nommée en implémentant Runnablel'interface ThreadClassTwo, réécrivez runla méthode et écrivez startla méthode. runLa méthode doit réaliser 0-10le nombre pair entre les impressions et le résultat est le suivant :0 2 4 6 8 10

/********** ThredClassOne.java **********/
package step1;

//请在此添加实现代码
/********** Begin **********/
public class ThreadClassOne extends Thread {
    private String name;
    
    public ThreadClassOne() {
        super();
    }
    public void run() {
        for (int i = 1; i < 10; i+=2) {
            System.out.print(i+" ");
        }
    }
}
/********** End **********/
/********** ThreadClassTwo.java **********/
package step1;

//请在此添加实现代码
/********** Begin **********/
public class ThreadClassTwo implements Runnable {
    private String name;
    private Thread mythread;
    public ThreadClassTwo () {
        super();
    }
    public void run() {
        for (int i = 0; i <=10; i+=2) {
            System.out.print(i+" ");
        }
    }
    public void start() {
        //System.out.println("线程开始: " + name);
        if (mythread == null) {
            mythread = new Thread(this, name);
            mythread.start();
        }
    }
}
/********** End **********/

Niveau 2 : Création de threads à l'aide de Callable et Future

informations connexes

Depuis Java1.5la version, Callableet Futurepour créer des threads, cette méthode est aussi Javaune question qui est souvent posée dans les interviews de programmeurs.

La section précédente a présenté Threaddeux manières de créer des threads, mais les deux manières de créer des threads ont un défaut : le résultat de l'exécution ne peut pas être obtenuRunnable après l'exécution de la tâche . Si vous avez besoin d'obtenir le résultat de l'exécution, vous devez obtenir l'effet en partageant des variables ou en utilisant la communication par thread, ce qui est plus gênant à utiliser.

Et si vous utilisez Callableet Future, vous pouvez obtenir le résultat de l'exécution de la tâche après l'exécution de la tâche à travers eux .

Les connaissances que vous devez maîtriser dans cette section sont :

1. Qu'est-ce que Callableet Future;

2. Comment passer Callableet Futurecréer des threads.

Callable和Future

Les deux sont en fait très intéressants, ils remplissent leurs fonctions pendant l'opération, Callableproduisent des résultats et Futureobtiennent des résultats .

Les étapes à utiliser sont les suivantes :

  1. Créez une classe d'implémentation de l'interface Callable et implémentez la méthode call(). La méthode call() sera utilisée comme corps d'exécution du thread et a une valeur de retour ;

  2. Créez une instance de la classe d'implémentation Callable, utilisez la classe FutureTask pour envelopper l'objet Callable et l'objet FutureTask encapsule la valeur de retour de la méthode call() de l'objet Callable ;

  3. Créez et démarrez un nouveau thread en utilisant l'objet FutureTask comme cible de l'objet Thread ;

  4. Appelez la méthode get() de l'objet FutureTask pour obtenir la valeur de retour une fois l'exécution du thread enfant terminée.

Ensuite, utilisez un exemple pour apprendre l'utilisation de ces deux objets :

public class Test {
    public static void main(String[] args) {
        CallableThreadTest cts = new CallableThreadTest();
        // 接收
        FutureTask<Integer> ft = new FutureTask<>(cts);
        new Thread(ft, "有返回值的线程").start();
        for (int i = 0; i < 30; i++) {
            System.out.println( "main" + " 的循环变量i的值:" + i);
        }
        try {
            System.out.println("子线程的返回值:" + ft.get());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
class CallableThreadTest implements Callable<Integer> {
    public Integer call() throws Exception {
        int i = 0;
        for (; i < 30; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
        return i;
    }
}
/*******************************/
运行这段程序你应该可以获取到类似如下结果(每次运行的结果不一致):
...
...
main 的循环变量i的值:28
main 的循环变量i的值:29
有返回值的线程 23
有返回值的线程 24
有返回值的线程 25
有返回值的线程 26
有返回值的线程 27
有返回值的线程 28
有返回值的线程 29
子线程的返回值:30

Parce que la sortie est trop longue, certains résultats sont omis et il peut être constaté que la valeur de retour du thread enfant est reçue à la fin.

Dans l'implémentation Callablede l'interface, il ne s'agit plus run()d'une méthode, mais call()d'une méthode. Cette call()méthode agit comme un corps d'exécution de thread et a également une valeur de retour !

Si vous faites attention, vous constaterez que ce résultat est callla valeur de retour de la fonction. Comment obtenez-vous cette valeur de retour ? Il est FutureTaskobtenu via ft.get()la méthode, et la valeur de retour du thread peut être obtenue en utilisant la méthode.C'est un Callable和Futureprocessus d'utilisation simple.

Nous en apprendrons davantage sur Callable和Futurel'utilisation et leurs fonctions communes dans la formation de suivi.

exigences de programmation

Begin - EndVeuillez lire attentivement le code sur la droite et compléter le code dans la zone en fonction des invites de la méthode . Les tâches spécifiques sont les suivantes :

  • Exécutez le thread dans runThread(int num)la fonction, créez Callablele thread, Callablele thread doit exécuter numla valeur de la séquence de Fibonacci, et enfin runThreadobtenir Callablele résultat de l'exécution du thread dans la fonction, et l'imprimer.

Séquence de Fibonacci (séquence de Fibonacci) Cette séquence 3commence à partir du premier élément et chaque élément suivant est égal à la somme de ses deux nombres précédents. Cette séquence est :1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368........

package step2;

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

public class Task {

	public void runThread(int num) {
    //请在此添加实现代码
/********** Begin **********/
// 在这里开启线程 获取线程执行的结果
ThreadCallable callable = new ThreadCallable(num);
	FutureTask<Integer> futureTask = new FutureTask<>(callable);
	new Thread(futureTask).start();//开启线程
	try {
		Integer result = futureTask.get();
		System.out.println("线程的返回值为:" + result);
	} catch (Exception e) {
		e.printStackTrace();
	}

/********** End **********/	
    }
}
//请在此添加实现代码
/********** Begin **********/

/* 在这里实现Callable接口及方法 */

class ThreadCallable implements Callable<Integer>{
	private int num;
    public ThreadCallable() {
    }
    public ThreadCallable(int num) {
        this.num = num;
    }
    public Integer call() throws Exception {//得到斐波那契数列的值
        int[] arr = new int[2];
        arr[0] = 1;
        arr[1] = 1;
        for (int i = 2; i < num; i++) {
            int temp = arr[1];
            arr[1] = arr[0] + arr[1];
            arr[0] = temp;
        }
        return arr[1];
    }
}
/********** End **********/

おすすめ

転載: blog.csdn.net/zhou2622/article/details/128382350