Il existe trois façons d'utiliser le multithreading Java : hériter de la classe Thread, implémenter l'interface Runnable et utiliser Callable et Future pour créer des threads.
1. Hériter de la classe Thread
L'implémentation est très simple. Il vous suffit de créer une classe pour hériter de la classe Thread et la remplacer. la méthode run. La concurrence multithread peut être obtenue en appelant la méthode start de l'objet instance de cette classe dans la méthode principale. Code :
public class MyThread extends Thread { @Override public void run(){ super.run(); System.out.println("执行子线程..."); } }
Scénario de test :
public class Test { public static void main(String[] args) { MyThread myThread = new MyThread(); myThread.start(); System.out.println("主线程..."); } }
Résultat d'exécution :
Bien entendu, les résultats ici ne représentent pas l'ordre d'exécution de les threads. Il est exécuté simultanément. S'il est exécuté plusieurs fois, l'ordre d'impression peut être différent. Lors d'une exécution multithread, le processeur exécute les threads de manière incertaine, de sorte que les résultats d'exécution n'ont rien à voir avec l'ordre d'exécution du code ou l'ordre d'appel, et les résultats d'exécution peuvent également être différents.
Tutoriels vidéo gratuits recommandés : Vidéo d'apprentissage Java
Un autre point à noter ici est que la méthode start de myThread doit être appelée dans la méthode principale, pas run () méthode. L'appel de la méthode start() indique au CPU que ce thread est prêt à être exécuté et le système exécutera sa méthode run() lorsqu'il en aura le temps.
Lors de l'appel direct de la méthode run(), elle n'est pas exécutée de manière asynchrone, mais exécutée de manière synchrone en séquence comme l'appel d'une fonction, ce qui perd le sens du multi-threading.
2. Implémenter l'interface Runnable
L'implémentation de cette méthode est également très simple, qui consiste à changer la classe Thread héritée pour l'implémenter. l'interface Runnable. Le code est le suivant :
public class MyRunnable implements Runnable { @Override public void run() { System.out.println("执行子线程..."); } }
Cas de test :
public class Test { public static void main(String[] args) { Runnable runnable = new MyRunnable(); Thread thread = new Thread(runnable); thread.start(); System.out.println("主线程运行结束!"); } }
Résultat d'exécution :
Le résultat d'exécution n'a rien à dire, vous peut le voir dans main ici Lorsqu'il s'agit de créer réellement un nouveau thread, il est toujours créé via Thread :
Thread thread = new Thread(runnable);
Le rôle de la classe Thread dans cette étape est d'empaqueter la méthode run() dans un thread corps d'exécution, puis utilisez toujours start pour indiquer au système que le thread est prêt à être planifié.
3. Utilisez Callable et Future pour créer des fils de discussion
Les deux méthodes ci-dessus ont ces deux problèmes :
1. La valeur de retour du thread enfant ne peut pas être obtenue ;
2. La méthode run ne peut pas lever d'exception.
Afin de résoudre ces deux problèmes, nous devons utiliser l'interface Callable. En parlant d'interfaces, l'instance de classe d'implémentation d'interface Runnable ci-dessus est transmise en tant que paramètre du constructeur de la classe Thread, puis le contenu de la méthode run est exécuté via le démarrage de Thread. Cependant, Callable n'est pas une sous-interface de Runnable, mais une toute nouvelle interface. Ses instances ne peuvent pas être directement transmises à la construction Thread, une autre interface est donc nécessaire pour la convertir.
Java5 fournit l'interface Future pour représenter la valeur de retour de la méthode call() dans l'interface Callable, et fournit une classe d'implémentation FutureTask pour l'interface Future. La relation d'héritage de la classe d'implémentation est telle qu'indiquée dans le. figure :
Comme vous pouvez le voir, cette classe d'implémentation implémente non seulement l'interface Future, mais implémente également l'interface Runnable, elle peut donc être transmise directement au constructeur Thread.
Le constructeur de FutureTask est le suivant :
Il y a donc en fait un processus de conversion de plus que la méthode précédente, et finalement un nouveau thread est créé via le démarrage de Thread. Avec cette idée, le code est facile à comprendre :
import java.util.concurrent.Callable; public class MyCallable implements Callable { int i = 0; @Override public Object call() throws Exception { System.out.println(Thread.currentThread().getName()+" i的值:"+ i); return i++; //call方法可以有返回值 } }
Test :
import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; public class Test { public static void main(String[] args) { Callable callable = new MyCallable(); for (int i = 0; i < 10; i++) { FutureTask task = new FutureTask(callable); new Thread(task,"子线程"+ i).start(); try { //获取子线程的返回值 System.out.println("子线程返回值:"+task.get() + "\n"); } catch (Exception e) { e.printStackTrace(); } } } }
Résultat de l'exécution (partie) :
Connexe Recommandé tutoriels d'articles : Programme d'entrée Java
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!