Java常用并发容器(concurrent包)

各种并发容器:
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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值