同步容器类包括Vector和HashTable,这两个都是JDK早期的容器。后来在JDK1.2也引入一个功能与之类似的类,这些同步的封装容器类是由Collections.synchronizedXXX等工厂方法创建的。这些类实现线程安全的方式是:将他们的状态封装起来,并对每个公有方法都进行同步,使得每次只有线程能访问容器的状态。
Vector:
Vector 类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。但是,Vector 的大小可以根据需要增大或缩小,以适应创建 Vector 后进行添加或移除项的操作。
构造函数:
Vector() 构造一个空向量,使其内部数据数组的大小为 10,其标准容量增量为零。 |
Vector(Collection<? extends E> c)
构造一个包含指定 collection 中的元素的向量,这些元素按其 collection 的迭代器返回元素的顺序排列。 |
Vector(int initialCapacity)
使用指定的初始容量和等于零的容量增量构造一个空向量。 |
Vector(int initialCapacity,
int capacityIncrement) 使用指定的初始容量和容量增量构造一个空的向量。 |
主要方法:
boolean |
add(E e) 将指定元素添加到此向量的末尾。 |
|
void |
add(int index, E element)
在此向量的指定位置插入指定的元素。 |
|
boolean |
addAll(Collection<? extends E> c)
将指定 Collection 中的所有元素添加到此向量的末尾,按照指定 collection 的迭代器所返回的顺序添加这些元素。 |
|
boolean |
addAll(int index,
Collection<? extends E> c)
在指定位置将指定 Collection 中的所有元素插入到此向量中。 |
|
void |
addElement(E obj)
将指定的组件添加到此向量的末尾,将其大小增加 1。 |
|
int |
capacity()
返回此向量的当前容量。 |
|
void |
clear()
从此向量中移除所有元素。 |
|
Object |
clone()
返回向量的一个副本。 |
|
boolean |
contains(Object o)
如果此向量包含指定的元素,则返回 true。 |
|
boolean |
containsAll(Collection<?> c)
如果此向量包含指定 Collection 中的所有元素,则返回 true。 |
|
void |
copyInto(Object[] anArray)
将此向量的组件复制到指定的数组中。 |
|
E |
elementAt(int index)
返回指定索引处的组件。 |
|
Enumeration<E> |
elements()
返回此向量的组件的枚举。 |
|
void |
ensureCapacity(int minCapacity)
增加此向量的容量(如有必要),以确保其至少能够保存最小容量参数指定的组件数。 |
|
boolean |
equals(Object o)
比较指定对象与此向量的相等性。 |
|
E |
firstElement()
返回此向量的第一个组件(位于索引 0) 处的项)。 |
|
E |
get(int index)
返回向量中指定位置的元素。 |
|
int |
hashCode()
返回此向量的哈希码值。 |
|
int |
indexOf(Object o)
返回此向量中第一次出现的指定元素的索引,如果此向量不包含该元素,则返回 -1。 |
|
int |
indexOf(Object o,
int index) 返回此向量中第一次出现的指定元素的索引,从 index
处正向搜索,如果未找到该元素,则返回 -1。 |
|
void |
insertElementAt(E obj,
int index) 将指定对象作为此向量中的组件插入到指定的 index
处。 |
|
boolean |
isEmpty()
测试此向量是否不包含组件。 |
|
E |
lastElement()
返回此向量的最后一个组件。 |
|
int |
lastIndexOf(Object o)
返回此向量中最后一次出现的指定元素的索引;如果此向量不包含该元素,则返回 -1。 |
|
int |
lastIndexOf(Object o,
int index) 返回此向量中最后一次出现的指定元素的索引,从 index
处逆向搜索,如果未找到该元素,则返回 -1。 |
|
E |
remove(int index)
移除此向量中指定位置的元素。 |
|
boolean |
remove(Object o)
移除此向量中指定元素的第一个匹配项,如果向量不包含该元素,则元素保持不变。 |
|
boolean |
removeAll(Collection<?> c)
从此向量中移除包含在指定 Collection 中的所有元素。 |
|
void |
removeAllElements()
从此向量中移除全部组件,并将其大小设置为零。 |
|
boolean |
removeElement(Object obj)
从此向量中移除变量的第一个(索引最小的)匹配项。 |
|
void |
removeElementAt(int index)
删除指定索引处的组件。 |
|
protected
void |
removeRange(int fromIndex,
int toIndex) 从此 List 中移除其索引位于 fromIndex(包括)与 toIndex(不包括)之间的所有元素。 |
|
boolean |
retainAll(Collection<?> c)
在此向量中仅保留包含在指定 Collection 中的元素。 |
|
E |
set(int index, E element)
用指定的元素替换此向量中指定位置处的元素。 |
|
void |
setElementAt(E obj,
int index) 将此向量指定 index
处的组件设置为指定的对象。 |
|
void |
setSize(int newSize)
设置此向量的大小。 |
|
int |
size()
返回此向量中的组件数。 |
|
List<E> |
subList(int fromIndex,
int toIndex) 返回此 List 的部分视图,元素范围为从 fromIndex(包括)到 toIndex(不包括)。 |
|
Object[] |
toArray()
返回一个数组,包含此向量中以恰当顺序存放的所有元素。 |
|
|
toArray(T[] a)
返回一个数组,包含此向量中以恰当顺序存放的所有元素;返回数组的运行时类型为指定数组的类型。 |
|
String |
toString()
返回此向量的字符串表示形式,其中包含每个元素的 String 表示形式。 |
|
void |
trimToSize()
对此向量的容量进行微调,使其等于向量的当前大小。 |
如果是单个方法进行调用是线程安全的,但是如果是组合的方式进行调用则需要再次进行同步处理
Vector 和 ArrayList 实现了同一接口 List, 但所有的 Vector 的方法都具有 synchronized 关键修饰。但对于复合操作,Vector 仍然需要进行同步处理
public static void main(String[] args) {
Vector<String> vector=new Vector();
for (int i = 0; i <12 ; i++) {
vector.add("第"+i+"名");
}
vector.remove(10);
for (String str:vector) {
System.out.println(str);
}
System.out.println(vector.size());
}
Stack
定义 栈是一种只能在一端进行插入或删除操作的线性表。(先进后出表)
Stack 类表示后进先出(LIFO)的对象堆栈。它通过五个操作对类 Vector 进行了扩展 ,允许将向量视为堆栈。它提供了通常的 push 和 pop 操作,以及取堆栈顶点的 peek 方法、测试堆栈是否为空的 empty 方法、在堆栈中查找项并确定到堆栈顶距离的 search 方法。
构造方法摘要:
Stack()
创建一个空堆栈。
方法摘要:
boolean |
empty() 测试堆栈是否为空。 |
E |
peek()
查看堆栈顶部的对象,但不从堆栈中移除它。 |
E |
pop()
移除堆栈顶部的对象,并作为此函数的值返回该对象。 |
E |
push(E item)
把项压入堆栈顶部。 |
int |
search(Object o)
返回对象在堆栈中的位置,以 1 为基数。 |
public static void main(String[] args) {
Stack<Integer> stack=new Stack<>();
int index=0;
for (int i = 0; i < 10; i++) {
stack.add(index++);
}
if(!stack.isEmpty()){
System.out.println("我不为空");
}
System.out.println(stack.peek());
System.out.println(stack.pop());
System.out.println(stack.push(20));
System.out.println(stack.search(3));
}
HashTable
哈希表(HashTable)又叫做散列表,是根据关键码值(即键值对)而直接访问的数据结构。也就是说,它通过把关键码映射到表中一个位置来访问记录,以加快查找速度。看到这里你可能比较疑惑,它是怎么加快查找速度的?下一节就有说明!这个映射函数就叫做散列(哈希)函数,存放记录的数组叫做散列表。
此类实现一个哈希表,该哈希表将键映射到相应的值。任何非 null 对象都可以用作键或值。
为了成功地在哈希表中存储和获取对象,用作键的对象必须实现 hashCode 方法和 equals 方法。
Hashtable 的实例有两个参数影响其性能:初始容量 和加载因子。容量 是哈希表中桶 的数量,初始容量 就是哈希表创建时的容量。
Collections.synchronized方法生成
构造方法摘要:
Hashtable() 用默认的初始容量 (11) 和加载因子 (0.75) 构造一个新的空哈希表。 |
Hashtable(int initialCapacity)
用指定初始容量和默认的加载因子 (0.75) 构造一个新的空哈希表。 |
Hashtable(int initialCapacity,
float loadFactor) 用指定初始容量和指定加载因子构造一个新的空哈希表。 |
Hashtable(Map<? extends K,? extends
V> t) 构造一个与给定的 Map 具有相同映射关系的新哈希表。 |
方法摘要:
void |
clear() 将此哈希表清空,使其不包含任何键。 |
Object |
clone()
创建此哈希表的浅表副本。 |
boolean |
contains(Object value)
测试此映射表中是否存在与指定值关联的键。 |
boolean |
containsKey(Object key)
测试指定对象是否为此哈希表中的键。 |
boolean |
containsValue(Object value) 如果此 Hashtable 将一个或多个键映射到此值,则返回 true。 |
Enumeration<V> |
elements()
返回此哈希表中的值的枚举。 |
Set<Map.Entry<K,V>> |
entrySet()
返回此映射中包含的键的 Set 视图。 |
boolean |
equals(Object o)
按照 Map 接口的定义,比较指定 Object 与此 Map 是否相等。 |
V |
get(Object key)
返回指定键所映射到的值,如果此映射不包含此键的映射,则返回 null. 更确切地讲,如果此映射包含满足
(key.equals(k)) 的从键 k 到值 v 的映射,则此方法返回
v;否则,返回 null。 |
int |
hashCode()
按照 Map 接口的定义,返回此 Map 的哈希码值。 |
boolean |
isEmpty()
测试此哈希表是否没有键映射到值。 |
Enumeration<K> |
keys()
返回此哈希表中的键的枚举。 |
Set<K> |
keySet()
返回此映射中包含的键的 Set 视图。 |
V |
put(K key, V value) 将指定 key 映射到此哈希表中的指定 value。 |
void |
putAll(Map<? extends K,? extends
V> t)
将指定映射的所有映射关系复制到此哈希表中,这些映射关系将替换此哈希表拥有的、针对当前指定映射中所有键的所有映射关系。 |
protected
void |
rehash()
增加此哈希表的容量并在内部对其进行重组,以便更有效地容纳和访问其元素。 |
V |
remove(Object key)
从哈希表中移除该键及其相应的值。 |
int |
size()
返回此哈希表中的键的数量。 |
String |
toString()
返回此 Hashtable 对象的字符串表示形式,其形式为 ASCII 字符 ", " (逗号加空格)分隔开的、括在括号中的一组条目。 |
Collection<V> |
values()
返回此映射中包含的键的 Collection 视图。 |
private static final int maxTHread=5000;//总线程数量
private static final int concurrenceTHread=200;//并发线程数
private static Map<Integer,Integer> map=new Hashtable();
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService=Executors.newCachedThreadPool();
final Semaphore semaphore=new Semaphore(concurrenceTHread);
final CountDownLatch countDownLatch=new CountDownLatch(maxTHread);
for (int i = 0; i < maxTHread; i++) {
final int count=i;
executorService.execute(()->{
try {
semaphore.acquire();//获取许可
update(count);
semaphore.release();//释放许可
} catch (Exception e) {
logger.info("result:"+e);
}
countDownLatch.countDown();//递减线程数量
});
}
countDownLatch.await();//等待
executorService.shutdown();//关闭线程池
logger.info("数量:"+map.size());
}
private static synchronized Integer update(int index){
return map.put(index,index);
}
Coollections工具类:
static
|
synchronizedCollection(Collection<T> c) 返回指定 collection 支持的同步(线程安全的)collection。 |
|
static
|
synchronizedList(List<T> list)
返回指定列表支持的同步(线程安全的)列表。 |
|
static
|
synchronizedMap(Map<K,V> m)
返回由指定映射支持的同步(线程安全的)映射。 |
|
static
|
synchronizedSet(Set<T> s) 返回指定 set 支持的同步(线程安全的)set。 |
|
static
|
synchronizedSortedMap(SortedMap<K,V> m)
返回指定有序映射支持的同步(线程安全的)有序映射。 |
|
static
|
synchronizedSortedSet(SortedSet<T> s)
返回指定有序 set 支持的同步(线程安全的)有序 set。 |
collections中不可变对象:
static
|
unmodifiableCollection(Collection<? extends T> c) 返回指定 collection 的不可修改视图。 |
|
static
|
unmodifiableList(List<? extends
T> list) 返回指定列表的不可修改视图。 |
|
static
|
unmodifiableMap(Map<? extends K,?
extends V> m) 返回指定映射的不可修改视图。 |
|
static
|
unmodifiableSet(Set<? extends
T> s) 返回指定 set 的不可修改视图。 |
|
static
|
unmodifiableSortedMap(SortedMap<K,? extends
V> m) 返回指定有序映射的不可修改视图。 |
|
static
|
unmodifiableSortedSet(SortedSet<T> s)
返回指定有序 set 的不可修改视图。 |
import com.google.common.collect.Lists; //Guava是一种基于开源的Java库,Google Guava源于2007年的"Google Collections Library"。
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>27.0.1-jre</version>
</dependency>
private static org.slf4j.Logger logger=LoggerFactory.getLogger(AtomicBoolExecutorService.class);
private static final int maxTHread=5000;//总线程数量
private static final int concurrenceTHread=200;//并发线程数
private static List<Integer> map=Collections.synchronizedList(Lists.newArrayList());
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService=Executors.newCachedThreadPool();
final Semaphore semaphore=new Semaphore(concurrenceTHread);
final CountDownLatch countDownLatch=new CountDownLatch(maxTHread);
for (int i = 0; i < maxTHread; i++) {
final int count=i;
executorService.execute(()->{
try {
semaphore.acquire();//获取许可
update(count);
semaphore.release();//释放许可
} catch (Exception e) {
logger.info("result:"+e);
}
countDownLatch.countDown();//递减线程数量
});
}
countDownLatch.await();//等待
executorService.shutdown();//关闭线程池
logger.info("数量:"+map.size());
}
private static void update(int index){
map.add(index);
}
- Collections.synchronized方法生成

浙公网安备 33010602011771号