In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-26 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)06/01 Report--
How to understand the Java synchronization container, in view of this problem, this article introduces the corresponding analysis and solution in detail, hoping to help more partners who want to solve this problem to find a more simple and feasible method.
> ArrayList,HashSet,HashMap is not thread-safe. In a multithreaded environment, it will cause thread-safety problems, so synchronization is needed when using it, which undoubtedly increases the difficulty of program development. So JAVA provides a synchronization container.
Synchronization container
ArrayList = = > Vector,Stack
HashMap = = > HashTable (key,value cannot be empty)
Collections.synchronizedXXX (List,Set,Map)
Vector implements the List interface, and the underlying layer is similar to ArrayList, but the methods in Vector are decorated with synchronized, that is, synchronization measures are carried out. However, Vector is not thread-safe.
Stack is also a synchronization container, which also uses synchronized for synchronization, inherits from Vector, and is in the data structure, first in and then out.
HashTable is similar to HashMap, but HashTable is synchronized.
The Collections utility class provides a large number of methods, such as sorting, finding, and other common operations on collections. At the same time, it also uses related methods to create synchronization container classes.
Vectorpackage com.rumenz.task;import java.util.List;import java.util.Vector;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;// thread safety public class VectorExample1 {public static Integer clientTotal=5000; public static Integer thradTotal=200; private static List list=new Vector (); public static void main (String [] args) throws Exception {ExecutorService executorService = Executors.newCachedThreadPool (); final Semaphore semaphore=new Semaphore (thradTotal) Final CountDownLatch countDownLatch=new CountDownLatch (clientTotal); for (int I = 0; I
< clientTotal; i++) { final Integer j=i; executorService.execute(()->{try {semaphore.acquire (); update (j); semaphore.release ();} catch (Exception e) {e.printStackTrace ();} countDownLatch.countDown ();}) } countDownLatch.await (); executorService.shutdown (); System.out.println ("size:" + list.size ());} private static void update (Integer j) {list.add (j);}} synchronization container is not necessarily thread-safe package com.rumenz.task;import scala.collection.convert.impl.VectorStepperBase;import java.util.List;import java.util.Vector Import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;// thread unsafe public class VectorExample2 {public static Integer clientTotal=5000; public static Integer threadTotal=200; private static List list=new Vector (); public static void main (String [] args) {ExecutorService executorService = Executors.newCachedThreadPool (); final Semaphore semaphore=new Semaphore (threadTotal); for (int I = 0; I
< threadTotal; i++) { list.add(i); } for (int i = 0; i < clientTotal; i++) { try{ semaphore.acquire(); executorService.execute(()->{for (int j = 0; j)
< list.size(); j++) { list.remove(j); } }); executorService.execute(()->{for (int j = 0; j)
< list.size(); j++) { list.get(j); } }); semaphore.release(); }catch (Exception e){ e.printStackTrace(); } } executorService.shutdown(); }}运行报错Exception in thread "pool-1-thread-2" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 36 at java.util.Vector.get(Vector.java:751) at com.rumenz.task.VectorExample2.lambda$main$1(VectorExample2.java:38) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)原因分析 >Vector is a thread synchronization container. Size (), get (), and remove () are all decorated by synchronized. Why is there a thread safety problem?
> the exception thrown by get () must be caused by remove (). Vector can guarantee that only one thread can enter at the same time, but:
/ / thread 1 executorService.execute (()-> {for (int j = 0; j)
< list.size(); j++) { list.remove(j); }});//线程2executorService.execute(()->{for (int j = 0; j)
< list.size(); j++) { list.get(j); }}); 线程1和线程2都执行完list.size(),都等于200,并且j=100 线程1执行list.remove(100)操作, 线程2执行list.get(100)就会抛出数组越界的异常。 >Although the synchronization container is thread-safe, it does not mean it is thread-safe in any environment.
HashTable
> Thread safety. Key,value cannot be null. It is inefficient to lock the entire HashTable when modifying data. Initial size=11.
Package com.rumenz.task;import java.util.Hashtable;import java.util.Map;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;// thread safety public class HashTableExample1 {public static Integer clientTotal=5000; public static Integer threadTotal=200; private static Map map=new Hashtable (); public static void main (String [] args) throws Exception {ExecutorService executorService = Executors.newCachedThreadPool (); final Semaphore semaphore=new Semaphore (threadTotal) Final CountDownLatch countDownLatch=new CountDownLatch (clientTotal); for (int I = 0; I
< clientTotal; i++) { final Integer j=i; try{ semaphore.acquire(); update(j); semaphore.release(); }catch (Exception e){ e.printStackTrace(); } countDownLatch.countDown(); } countDownLatch.await(); executorService.shutdown(); System.out.println("size:"+map.size()); } private static void update(Integer j) { map.put(j, j); }}//size:5000Collections.synchronizedList线程安全package com.rumenz.task.Collections;import com.google.common.collect.Lists;import java.util.Collections;import java.util.List;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;//线程安全public class synchronizedExample { public static Integer clientTotal=5000; public static Integer threadTotal=200; private static List list=Collections.synchronizedList(Lists.newArrayList()); public static void main(String[] args) throws Exception{ ExecutorService executorService = Executors.newCachedThreadPool(); final Semaphore semaphore=new Semaphore(threadTotal); final CountDownLatch countDownLatch=new CountDownLatch(clientTotal); for (int i = 0; i < clientTotal; i++) { final Integer j=i; try{ semaphore.acquire(); update(j); semaphore.release(); }catch (Exception e){ e.printStackTrace(); } countDownLatch.countDown(); } countDownLatch.await(); executorService.shutdown(); System.out.println("size:"+list.size()); } private static void update(Integer j) { list.add(j); }}//size:5000Collections.synchronizedSet线程安全package com.rumenz.task.Collections;import com.google.common.collect.Lists;import org.assertj.core.util.Sets;import java.util.Collections;import java.util.List;import java.util.Set;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;//线程安全public class synchronizedSetExample { public static Integer clientTotal=5000; public static Integer threadTotal=200; private static Set set=Collections.synchronizedSet(Sets.newHashSet()); public static void main(String[] args) throws Exception{ ExecutorService executorService = Executors.newCachedThreadPool(); final Semaphore semaphore=new Semaphore(threadTotal); final CountDownLatch countDownLatch=new CountDownLatch(clientTotal); for (int i = 0; i < clientTotal; i++) { final Integer j=i; try{ semaphore.acquire(); update(j); semaphore.release(); }catch (Exception e){ e.printStackTrace(); } countDownLatch.countDown(); } countDownLatch.await(); executorService.shutdown(); System.out.println("size:"+set.size()); } private static void update(Integer j) { set.add(j); }}//size:5000Collections.synchronizedMap线程安全package com.rumenz.task.Collections;import org.assertj.core.util.Sets;import java.util.Collections;import java.util.HashMap;import java.util.Map;import java.util.Set;import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;public class synchronizedMapExample { public static Integer clientTotal=5000; public static Integer threadTotal=200; private static Map map=Collections.synchronizedMap(new HashMap()); public static void main(String[] args) throws Exception{ ExecutorService executorService = Executors.newCachedThreadPool(); final Semaphore semaphore=new Semaphore(threadTotal); final CountDownLatch countDownLatch=new CountDownLatch(clientTotal); for (int i = 0; i < clientTotal; i++) { final Integer j=i; try{ semaphore.acquire(); update(j); semaphore.release(); }catch (Exception e){ e.printStackTrace(); } countDownLatch.countDown(); } countDownLatch.await(); executorService.shutdown(); System.out.println("size:"+map.size()); } private static void update(Integer j) { map.put(j, j); }}//size:5000 >During the iteration of Collections.synchronizedXXX, developers need to add thread lock control code themselves, because there is no synchronization code outside the loop during the whole iteration. Between iterations, other threads' add or remove of this container will affect the expected effect of the whole iteration. In this case, you need to add synchronized (XXX) to the loop.
Deletion of collections
If you are traversing the collection using foreach or iterator
Try not to update remove and other related operations during the operation.
If you have to do an operation, you can record the sequence number of the required action element during the traversal
Do not operate until the traversal is over, so that the two actions can be carried out separately.
Package com.rumenz.task;import com.google.common.collect.Lists;import java.util.Collections;import java.util.Iterator;import java.util.List;public class CollectionsExample {private static List list=Collections.synchronizedList (Lists.newArrayList ()); public static void main (String [] args) {list.add (1); list.add (2); list.add (3); list.add (4); / / del1 () / / del2 (); del3 ();} private static void del3 () {for (Integer i:list) {if (iTunes 4) {list.remove (I);}} / / Exception in thread "main" java.util.ConcurrentModificationException private static void del2 () {Iterator iterator = list.iterator () While (iterator.hasNext ()) {Integer I = iterator.next (); if (iTunes 4) {list.remove (I);}} / / Exception in thread "main" java.util.ConcurrentModificationException private static void del1 () {for (int I = 0; I)
< list.size(); i++) { if(list.get(i)==4){ list.remove(i); } } }} >The above errors will occur in a single thread, in the case of multithreading, and shared during collection, the probability of exception will be greater, which requires special attention. The solution is to mark the elements to be operated on when you foreach or iterator, and then perform the relevant actions after the loop is over.
> the synchronization container uses synchronized for synchronization, so the performance of execution will be affected, and the synchronization container may not be thread-safe.
The answer to the question on how to understand the Java synchronization container is shared here. I hope the above content can be of some help to you. If you still have a lot of doubts to be solved, you can follow the industry information channel for more related knowledge.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.