Dans les applications monothread, new ArrayList() est généralement utilisé pour spécifier une collection List pour stocker des données répétables.
Mais en multithreading, des problèmes inattendus surviennent souvent. Le code est le suivant :
import java.util.*; public class ListTest { public static void main(String[] args) throws InterruptedException { // 创建list集合 //List<String> lists = Arrays.asList("1", "2", "3"); // 不安全 List<String> lists = new ArrayList<>(); // 开启十个线程增加数据 for (int i = 1; i <= 40; i++) { new Thread(()->{ lists.add(UUID.randomUUID().toString().substring(0,5)); System.out.println(Thread.currentThread().getName()+"=="+lists); },String.valueOf(i)).start(); } } }
Lorsque plusieurs threads exploitent la même collection d'informations sur les objets, des messages d'erreur d'exception java.util.ConcurrentModificationException apparaissent souvent.
Dans le langage Java, une nouvelle collection List, la classe java.util.Vector, est fournie. Voir le code suivant pour plus de détails :
import java.util.*; public class ListTest { public static void main(String[] args) throws InterruptedException { // 创建list集合 //List<String> lists = Arrays.asList("1", "2", "3"); // 不安全 //List<String> lists = new ArrayList<>(); List<String> lists = new Vector<>(); // 开启十个线程增加数据 for (int i = 1; i <= 40; i++) { new Thread(()->{ lists.add(UUID.randomUUID().toString().substring(0,5)); System.out.println(Thread.currentThread().getName()+"=="+lists); },String.valueOf(i)).start(); } } }
Il n'y aura pas d'erreur java.util.ConcurrentModificationException. message.
Pourquoi pouvons-nous garantir le fonctionnement sécurisé des données ?
adopte un verrouillage synchronisé pour l'appelant d'exécution de méthode afin de garantir la sécurité multithread de l'opération d'ajout !
Dans le cadre du package JUC, les méthodes suivantes pour créer une collection sécurisée sont fournies.
Méthode 1 : Collections.synchronizedList(new ArrayList<>());
import java.util.*; public class ListTest { public static void main(String[] args) throws InterruptedException { List<String> lists = Collections.synchronizedList(new ArrayList<>()); // 开启十个线程增加数据 for (int i = 1; i <= 40; i++) { new Thread(()->{ lists.add(UUID.randomUUID().toString().substring(0,5)); System.out.println(Thread.currentThread().getName()+"=="+lists); },String.valueOf(i)).start(); } } }
Affichez le code source sous-jacent pour implémenter la logique
Jugez le type de collection de liste entrante et déterminez si le le type est java. util.RandomAccess, si c'est le cas, utilisez java.util.Collections.SynchronizedRandomAccessList pour construire la collection, sinon, utilisez java.util.Collections.SynchronizedList pour construire la collection.
La logique de l'opération d'ajout correspondante dans le code source est la suivante :
Adoptez un bloc de code de synchronisation synchronisé pour verrouiller l'opération d'ajout de données ! Méthode C 2 : New CopyonWriteArrayList ();
import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; public class ListTest { public static void main(String[] args) throws InterruptedException { List<String> lists = new CopyOnWriteArrayList<>(); // 开启十个线程增加数据 for (int i = 1; i <= 40; i++) { new Thread(()->{ lists.add(UUID.randomUUID().toString().substring(0,5)); System.out.println(Thread.currentThread().getName()+"=="+lists); },String.valueOf(i)).start(); } } }
Évidemment, la logique est la suivante :
Après avoir appelé la méthode ADD , prenez-le, prenez-le, prenez-le, prenez-le, prenez la méthode ADD pour les informations sur l'objet java.util.concurrent.locks.ReentrantLock.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!