各种并发容器:
Map
HashTable
HashMap ( Collections.synchronizedMap(Map<?,?> map) )
ConcurrentHashMap
ConcurrentSkipListMap
List
CopyOnWriteList
性能比较:
需求:100个线程,每个线程往容器里放10000个数据,比较线程执行时间长短。
1.HashTable(相当于把hashMap的方法加锁,效率低)
1
public class TestHashTable{
2
public static void main(String[] args){
3
Map<String, String> map = new HashTable<>();//初始化容器
4
5
Random r = new Random();
6
Thread[] threads = new Thread[100];//线程数组放100个线程
7
CountDownLatch latch = new CountDownLatch(this.length);
8
long start = System.currentTimeMillis();//----------------记录线程起始时间
9
for(int i=0;i<threads.length;i++){
10
threads[i] = new Threads(()->{
11
for(int j=0;j<10000;j++) map.put("key",r.nextInt(10000));//100个线程每个线程往容器放10000个数据
12
latch.countDown();//门栓计数器减1,当100个线程都结束时,门栓技术器为0,唤醒主线程打印
13
});
14
}
15
for(Thread t : threads){
16
t.start();//开启100个线程
17
}
18
try{
19
latch.await();//等待100个子线程执行完被唤醒
20
}catch(InterruptException e){
21
e.printStackTrace();
22
}
23
long end = System.currentTimeMillis();//-----------------------------记录结束时间
24
System.out.println("共耗时:" + end - start);
25
}
26
27
}
28
//实验结果700+ms
2.
ConcurrentHashMap(效率高)
1
public class TestConcurrentHashMap{
2
public static void main(String[] args){
3
Map<String, String> map = new ConcurrentHashMap<>();//初始化容器
4
5
Random r = new Random();
6
Thread[] threads = new Thread[100];//线程数组放100个线程
7
CountDownLatch latch = new CountDownLatch(this.length);
8
long start = System.currentTimeMillis();//----------------记录线程起始时间
9
for(int i=0;i<threads.length;i++){
10
threads[i] = new Threads(()->{
11
for(int j=0;j<10000;j++) map.put("key",r.nextInt(10000));//100个线程每个线程往容器放10000个数据
12
latch.countDown();//门栓计数器减1,当100个线程都结束时,门栓技术器为0,唤醒主线程打印
13
});
14
}
15
for(Thread t : threads){
16
t.start();//开启100个线程
17
}
18
try{
19
latch.await();//等待100个子线程执行完被唤醒
20
}catch(InterruptException e){
21
e.printStackTrace();
22
}
23
long end = System.currentTimeMillis();//-----------------------------记录结束时间
24
System.out.println("共耗时:" + end - start);
25
}
26
27
}
28
//实验结果610ms
ConcurrentHashMap比HashTable效率高的原因:
HashTable:每次锁定的是整存储数据的数组(增加删除数据串行执行,不能同时操作多个数据)
ConcurrentHashMap:每次只锁定存储数组的一段(将数组分成16段锁定,细化了锁粒度),可同时操作多个数据。
3.ConcurrentSkipListMap跳表map(高并发且排序,插入效率低,查询效率高)
1
public class TestConcurrentSkipListMap{
2
public static void main(String[] args){
3
Map<String, String> map = new ConcurrentSkipListMap<>();//初始化容器
4
5
Random r = new Random();
6
Thread[] threads = new Thread[100];//线程数组放100个线程
7
CountDownLatch latch = new CountDownLatch(this.length);
8
long start = System.currentTimeMillis();//----------------记录线程起始时间
9
for(int i=0;i<threads.length;i++){
10
threads[i] = new Threads(()->{
11
for(int j=0;j<10000;j++) map.put("key",r.nextInt(10000));//100个线程每个线程往容器放10000个数据
12
latch.countDown();//门栓计数器减1,当100个线程都结束时,门栓技术器为0,唤醒主线程打印
13
});
14
}
15
for(Thread t : threads){
16
t.start();//开启100个线程
17
}
18
try{
19
latch.await();//等待100个子线程执行完被唤醒
20
}catch(InterruptException e){
21
e.printStackTrace();
22
}
23
long end = System.currentTimeMillis();//-----------------------------记录结束时间
24
System.out.println("共耗时:" + end - start);
25
}
26
27
}
28
//实验结果1000+ms
4.CopyOnWriteList(
写时复制。添加元素--》复制容器---》容器2为新容器(带有插入的新数据),容器1为旧容器,此时另一个线程读数据读的是容器1的数据,不需要加锁)
读的效率高,写的效率低
1
public class TestCopyOnWriteList{
2
public static void main(String[] args){
3
List<String> list = new CopyOnWriteList<>();//初始化容器
4
5
Random r = new Random();
6
Thread[] threads = new Thread[100];//线程数组放100个线程
7
CountDownLatch latch = new CountDownLatch(this.length);
8
long start = System.currentTimeMillis();//----------------记录线程起始时间
9
for(int i=0;i<threads.length;i++){
10
threads[i] = new Threads(()->{
11
for(int j=0;j<1000;j++) list.add("key"+r.nextInt(10000));//100个线程每个线程往容器放1000个数据
12
latch.countDown();//门栓计数器减1,当100个线程都结束时,门栓技术器为0,唤醒主线程打印
13
});
14
}
15
for(Thread t : threads){
16
t.start();//开启100个线程
17
}
18
try{
19
latch.await();//等待100个子线程执行完被唤醒
20
}catch(InterruptException e){
21
e.printStackTrace();
22
}
23
long end = System.currentTimeMillis();//-----------------------------记录结束时间
24
System.out.println("共耗时:" + end - start);//计算运行时间
25
System.out.println("数组大小:" + list.size());//100000
26
}
27
28
}
29
//实验结果5600+ms