Dans le développement multithread quotidien, nous pouvons parfois vouloir laisser chaque thread s'exécuter dans l'ordre que nous spécifions, au lieu de laisser le processeur le planifier de manière aléatoire. des problèmes inutiles dans le travail de développement quotidien.
Maintenant que cette exigence existe, le titre de cet article est introduit pour permettre aux threads de s'exécuter dans l'ordre spécifié par eux-mêmes.
Les étudiants intéressés peuvent deviner les résultats possibles de l'exécution du code suivant :
Selon une compréhension normale, l'ordre d'exécution du code ci-dessus devrait être : t1 &rarr t2 → pas un état idéal.
L'image ci-dessous montre l'effet de course :
Join n'est peut-être pas étranger à certains étudiants. Je ne présenterai pas ce qu'est Join en détail ici. Les étudiants qui ont des questions peuvent baidu et. Google.
Ici, je vais vous présenter directement comment utiliser join pour obtenir l'effet que nous souhaitons voir !
Ici, nous utilisons principalement l'effet bloquant de Join pour atteindre notre objectif. En regardant les résultats d'exécution dans la figure ci-dessus, nous pouvons savoir que le programme a été exécuté dans l'ordre que nous avons spécifié et a obtenu les résultats souhaités.
En fait, nous pouvons réfléchir profondément à la raison pour laquelle adhérer peut obtenir l'effet que nous souhaitons ? Ensuite, jetons un coup d'œil au code source :
Après avoir entré le code source de jointure, la première chose que vous voyez est une méthode de jointure qui passe 0 paramètre. Ici, choisissez de continuer la saisie.
Tout d'abord, vous pouvez voir que la méthode join est thread-safe. Deuxièmement, vous pouvez la voir avec l'image ci-dessus. Lorsque le paramètre entrant est 0, une méthode wait(0) sera exécutée. Les étudiants expérimentés devraient pouvoir le voir directement. Comprenez, cela signifie attendre.
Mais il convient de noter que l'attente ici n'est certainement pas l'attente de l'appelant, mais les threads principaux bloqués t1, t2 et t3 ne sont que des sous-threads. Lorsque les sous-threads ont fini de s'exécuter, le thread principal termine son attente. .
Cela démontre comment fonctionne join, et prouve également que join peut nous permettre d'obtenir les résultats que nous souhaitons dans le programme.
En plus de nous aider à contrôler l'ordre des threads dans le programme, il existe d'autres moyens. Par exemple, essayons d'utiliser le pool de threads.
Executors est la classe d'opérations de pool de threads sous le package java.util.concurrent dans le JDK, qui peut facilement nous fournir des opérations de pool de threads.
Ici, nous utilisons la méthode newSingleThreadExecutor() dans Executors pour créer un pool de threads à un seul thread.
Comme le montre la figure ci-dessus, l'utilisation de la méthode newSingleThreadExecutor() peut toujours obtenir les résultats que nous attendons. En fait, l'intérieur de la méthode est une file d'attente basée sur FIFO. c'est-à-dire que lorsque nous ajoutons séquentiellement t1, t2 Lorsque t3 est ajouté à la file d'attente, seul le thread t1 est réellement à l'état prêt et t3 sera ajouté à la file d'attente lorsque t1 est terminé, les autres threads de la file d'attente. continuera à être exécuté.
Lors de l'apprentissage des opérateurs, les lecteurs savent qu'il existe une priorité entre les opérateurs. Comprendre la priorité des opérateurs a un bon effet sur le développement du programme. Il en va de même pour les threads. Chaque thread a une priorité. La machine virtuelle Java détermine l'ordre d'exécution des threads en fonction de la priorité du thread, afin que plusieurs threads puissent raisonnablement partager les ressources CPU sans conflit.
Dans le langage Java, la plage de priorité d'un thread est de 1 à 10 et la valeur doit être comprise entre 1 et 10, sinon une exception se produira ; la valeur par défaut de la priorité est de 5. Les threads avec une priorité plus élevée seront exécutés en premier, et une fois l'exécution terminée, ce sera au tour des threads avec une priorité inférieure de s'exécuter. Si les priorités sont les mêmes, elles seront exécutées à tour de rôle.
Vous pouvez utiliser la méthode setPriority() dans la classe Thread pour définir la priorité du thread. La syntaxe est la suivante :
public final void setPriority(int newPriority);
Si vous souhaitez obtenir la priorité du thread actuel, vous pouvez appeler directement la méthode getPriority(). La syntaxe est la suivante :
public final int getPriority();
Après avoir brièvement compris les priorités, utilisons un exemple simple pour montrer comment utiliser les priorités.
Exemple 1
Créez des threads en utilisant respectivement la classe Thread et l'interface Runnable, et attribuez-leur des priorités.
public class FirstThreadInput extends Thread { public void run() { System.out.println("调用FirstThreadInput类的run()重写方法"); //输出字符串 for(int i=0;i<5;i++) { System.out.println("FirstThreadInput线程中i="+i); //输出信息 try { Thread.sleep((int) Math.random()*100); //线程休眠 } catch(Exception e){} } } }
(2) Créez une classe SecondThreadInput qui implémente l'interface Runnable et implémente la méthode run(). Le code est le suivant :
public class SecondThreadInput implements Runnable { public void run() { System.out.println("调用SecondThreadInput类的run()重写方法"); //输出字符串 for(int i=0;i<5;i++) { System.out.println("SecondThreadInput线程中i="+i); //输出信息 try { Thread.sleep((int) Math.random()*100); //线程休眠 } catch(Exception e){} } } }
(3) 创建 TestThreadInput 测试类,分别使用 Thread 类的子类和 Runnable 接口的对象创建线程,然后调用 setPriority() 方法将这两个线程的优先级设置为 4,最后启动线程。代码如下:
public class TestThreadInput { public static void main(String[] args) { FirstThreadInput fti=new FirstThreadInput(); Thread sti=new Thread(new SecondThreadInput()); fti.setPriority(4); sti.setPriority(4); fti.start(); sti.start(); } }
(4) 运行上述代码,运行结果如下所示。
调用FirstThreadInput类的run()重写方法
调用SecondThreadInput类的run()重写方法
FirstThreadInput线程中i=0
SecondThreadInput线程中i=0
FirstThreadInput线程中i=1
FirstThreadInput线程中i=2
SecondThreadInput线程中i=1
FirstThreadInput线程中i=3
SecondThreadInput线程中i=2
FirstThreadInput线程中i=4
SecondThreadInput线程中i=3
SecondThreadInput线程中i=4
由于该例子将两个线程的优先级都设置为 4,因此它们交互占用 CPU ,宏观上处于并行运行状态。
重新更改 ThreadInput 类的代码、设置优先级。代码如下:
fti.setPriority(1); sti.setPriority(10);
重新运行上述代码,如下所示。
调用FirstThreadInput类的run()重写方法
调用SecondThreadInput类的run()重写方法
FirstThreadInput线程中i=0
SecondThreadInput线程中i=0
SecondThreadInput线程中i=1
SecondThreadInput线程中i=2
SecondThreadInput线程中i=3
SecondThreadInput线程中i=4
FirstThreadInput线程中i=1
FirstThreadInput线程中i=2
FirstThreadInput线程中i=3
FirstThreadInput线程中i=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!