Cet article présente principalement des informations pertinentes sur le résumé de plusieurs méthodes d'exécution ordonnée de Java multi-thread. Les amis dans le besoin peuvent se référer à ce qui suit
Plusieurs méthodes d'exécution ordonnée de Java multi-thread.
Un collègue a soulevé cette question accidentellement et a pratiqué personnellement deux méthodes. Bien sûr, il existe certainement des moyens plus nombreux et meilleurs.
Méthode 1
import java.util.concurrent.atomic.AtomicInteger; public class OrderedThread1 { static AtomicInteger count = new AtomicInteger(0); public static void main(String[] args) throws InterruptedException { Task task1 = new Task(count, 0); Task task2 = new Task(count, 1); Task task3 = new Task(count, 2); Thread thread1 = new Thread(task1); Thread thread2 = new Thread(task2); Thread thread3 = new Thread(task3); thread1.setDaemon(true); thread2.setDaemon(true); thread3.setDaemon(true); thread1.start(); thread2.start(); thread3.start(); Thread.sleep(1 * 1000); } } class Task implements Runnable { private AtomicInteger count; private int order; public Task(AtomicInteger count, int order) { this.count = count; this.order = order; } @Override public void run() { while (true) { if (count.get() % 3 == order) { System.out.println(Thread.currentThread().getName() + " ===== "+ order); count.incrementAndGet(); } } } }
Cette méthode devrait être une solution plus courante. Utilisez l'incrément atomique pour contrôler l'ordre d'admission des threads.
Méthode 2
public class OrderedThread2 { static Holder holder = new Holder(); public static void main(String[] args) throws InterruptedException { Task1 task1 = new Task1(holder, 0); Task1 task2 = new Task1(holder, 1); Task1 task3 = new Task1(holder, 2); Thread thread1 = new Thread(task1); Thread thread2 = new Thread(task2); Thread thread3 = new Thread(task3); thread1.setDaemon(true); thread2.setDaemon(true); thread3.setDaemon(true); thread1.start(); thread2.start(); thread3.start(); Thread.sleep(1 * 1000); } } class Task1 implements Runnable { Holder holder; int order; public Task1(Holder holder, int order) { this.holder = holder; this.order = order; } @Override public void run() { while (true) { if (holder.count % 3 == order) { System.out.println(Thread.currentThread().getName() + " ===== "+ order); holder.count ++; } } // int i = 0; // while(i ++ < 10000){ // holder.count ++; // } } } class Holder { volatile int count = 0; }
La méthode 2 utilise le mot-clé volatile. Laissez chaque thread obtenir la dernière valeur de comptage. Lorsque l'un des threads effectue l'opération, les deux autres threads obtiendront la dernière valeur et vérifieront si les conditions d'admission sont remplies.
ps : volatile n'est pas thread-safe. Et les deux n’ont rien à voir l’un avec l’autre. Les variables volatiles ne conservent pas de copies dans les threads utilisateur, elles fournissent donc la dernière valeur à tous les threads. Mais imaginez, si plusieurs threads simultanément mettent à jour la variable en même temps, le résultat est évident. La dernière mise à jour écrasera toutes les mises à jour précédentes, provoquant une insécurité des threads. Dans la deuxième méthode, un seul thread remplit la condition d'admission à la fois, il n'y a donc pas de mise à jour simultanée des variables. Garder les valeurs volatiles à jour n'a absolument aucun rapport avec la sécurité des threads, alors n'utilisez pas volatile pour implémenter le contrôle de concurrence.
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!