JDK 1.5 以前同步容器包括:html
- Vector、Hashtable、Stack
- Collections 工具類將普通容器,轉變爲同步容器,如:
public static <T> Collection<T> synchronizedCollection(Collection<T> c) public static <T> Set<T> synchronizedSet(Set<T> s) public static <T> List<T> synchronizedList(List<T> list) public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)
同步容器的實現原理就是在容器的操做方法上,加上了 synchronized 關鍵字。java
List:CopyOnWriteArrayList面試
- Set:CopyOnWriteArraySet、ConcurrentSkipListSet
- Map:ConcurrentHashMap、ConcurrentSkipListMap
- Queue:阻塞隊列名稱用 Blocking 標識,單端隊列名稱用 Queue 標識,雙端隊列名稱用 Deque 標識
- 單端阻塞隊列:ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue、LinkedTransferQueue、PriorityBlockingQueue、DelayQueue
- 雙端阻塞隊列:LinkedBlockingDeque
- 單端非阻塞隊列:ConcurrentLinkedQueue
- 雙端非阻塞隊列:ConcurrentLinkedDeque
下面示例中,當不把 list 轉變爲同步容器,併發 add,最後主線程打印 list,可能會報 java.util.ConcurrentModificationException 和 java.lang.ArrayIndexOutOfBoundsException,去掉註釋就能夠併發新增元素(固然最後打印的 list 不必定是元素的狀況)小程序
package constxiong.interview; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * 測試 同步容器與併發容器 * @author ConstXiong * @date 2019-12-26 20:56:32 */ public class TestSynchronizedAndConcurrentCollection { static List<Integer> list = new ArrayList<Integer>(); public static void main(String[] args) throws InterruptedException { testSynchronizedCollection(); } /** * 測試同步容器 * @throws InterruptedException */ private static void testSynchronizedCollection() throws InterruptedException { // list = Collections.synchronizedList(list); for (int i = 0; i < 300; i++) { final int index = i; new Thread(() -> { list.add(index); }).start(); } System.out.println(list); } }
併發容器的使用很簡單,跟普通容器相似,如:併發
/** * 測試併發容器 */ private static void testConcurrentCollection() { for (int i = 0; i < 300; i++) { final int index = i; new Thread(() -> { map.put(index, index); }).start(); } System.out.println(map); }
原文連接
工具
- Java 自學經歷
- Java 面試題 H5
- Java 面試題小程序