1. ConcurrentSkipListMap
- 概述:底层使用跳表来快速操作元素;利于查询。
- API使用
public class ConcurrentSkipListMapTest {
ConcurrentSkipListMap<Integer, String> map = new ConcurrentSkipListMap<>();
@Before
public void initSkipListMap() {
map.put(1, "C");
map.put(5, "C++");
map.put(10, "JAVA");
}
@Test
public void testCeiling() {
assertThat(map.ceilingKey(2), equalTo(5));
assertThat(map.ceilingEntry(2).getValue(), equalTo("C++"));
}
@Test
public void testFloor() {
assertThat(map.floorKey(2), equalTo(1));
assertThat(map.floorEntry(2).getValue(), equalTo("C"));
}
@Test
public void testFirst() {
assertThat(map.firstKey(), equalTo(1));
assertThat(map.firstEntry().getValue(), equalTo("C"));
}
@Test
public void testLast() {
assertThat(map.lastKey(), equalTo(10));
assertThat(map.lastEntry().getValue(), equalTo("JAVA"));
}
@Test
public void testMerge() {
assertThat(map.merge(1, "C--", (oldValue, newValue) -> {
System.out.println("old: " + oldValue);
System.out.println("new: " + newValue);
return oldValue + newValue;
}), equalTo("CC--"));
assertThat(map.get(1), equalTo("CC--"));
}
@Test
public void testCompute() {
assertThat(map.compute(1, (key, newValue) -> {
System.out.println("key: " + key);
System.out.println("value: " + newValue);
return key + newValue;
}), equalTo("1C"));
assertThat(map.get(1), equalTo("1C"));
}
}
2. ConcurrentLinkedQueue
- 使用时需要注意的点:遍历时, 使用isEmpty判断queue是否为空; 不要判断size;size会遍历整个queue获取queue的元素个数; 非常耗时。
public class ConcurrentListQueueTest {
@Test
public void testSize() {
ConcurrentLinkedQueue<Long> queue = new ConcurrentLinkedQueue();
for (int i = 0; i < 1000000; i++) {
queue.add(System.currentTimeMillis());
}
long startTime = System.currentTimeMillis();
while (!queue.isEmpty()) {
System.out.println(queue.poll());
}
System.out.println(System.currentTimeMillis() - startTime);
}
}
2. CopyOnWriteArrayList & CopyOnWriteArraySet
- 概述:主要使用copyOnWrite的思想去保证原子性;对于写操作都会加锁,然后,创建一个的集合出来,把原集合的数据复制到新集合中;然后,修改原集合的指向到新集合上;因此,这样就保证了读操作,都是无锁的操作;