多线程环境使用ArrayList
1.Vector(已过时)
在Java早期使用Vector,在remove、get、set、add、size都是通过synchronized修饰,但是Vector已经过时了,效率比较慢。
2.Synchronized或者ReentrantLock修饰
3.Collections.synchronizedList
List<String> arrayList = new ArrayList<>();
arrayList.add("123");
arrayList.add("234");
arrayList.add("345");
List<String> strings = Collections.synchronizedList(arrayList);
Collections.synchronizedList底层返回的是SynchronizedList,关键代码是同步代码块如下:
public E get(int index) {
synchronized (mutex) {return list.get(index);}
}
public E set(int index, E element) {
synchronized (mutex) {return list.set(index, element);}
}
public void add(int index, E element) {
synchronized (mutex) {list.add(index, element);}
}
public E remove(int index) {
synchronized (mutex) {return list.remove(index);}
}
4.CopyOnWriteArrayList(写数组的拷贝)
List<String> list = new CopyOnWriteArrayList<String>();
多线程环境使用HashMap
1.HashTable(已过时)
效率太慢,HashMap后期做了很多优化,Hash Table没有同步
2.ConcurrentHashMap
内部采用分段锁机制,效率比较高。
3.Collections.synchronizedMap
Map<String, String> map = Collections.synchronizedMap(new HashMap<>());
Set
1.CopyOnWriteArraySet
2.Collections.synchronizedSet()
3.Collections.newSetFromMap()
Set<String> setFromMap = Collections.newSetFromMap(new ConcurrentHashMap<>());
4.ConcurrentHashMap.newKeySet()
队列
使用Jdk提供的阻塞队列BlockingQueue
- ArrayBlockingQueue 数组有界队列
- ConcurrentLinkedQueue 链表有界队列
- PriorityBlockingQueue 优先级排序无界队列
- DelayQueue 延时无界队列
如果要操作线程不安全的容器,如何让它变成线程安全?
List: Collections.synchronizedList();
Map: Collections.synchronizedMap();
Set: Collections.synchronizedSet();