Java多线程系列六——Map实现类
参考资料:
https://stackoverflow.com/questions/35534906/java-hashmap-getobject-infinite-loop
Map的一些实现类有及其特性
|
类 |
线程安全 | 特性 |
|
Hashtable |
是 | Key不能为null |
|
HashMap |
否 | 读写效率最高,但在Java6多线程环境下使用不当可能陷入死循环,进而导致CPU使用率过高(原理可参见:http://coolshell.cn/articles/9606.html) |
|
Collections.synchronizedMap |
是 | Collections.SynchronizedMap在Map所有方法基础上加锁,效率与HashTable相当 |
|
ConcurrentHashMap |
是 | 采用分段锁,get一般不加锁,put分段锁,key/value不能为null,效率仅次于HashMap |
以下代码测试各类的读写效率
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; /**
* @Description: 测试map
*/
public class ThreadMapTest {
public static void main(String[] args) throws InterruptedException {
Map<Integer, Integer> hashtable = new Hashtable<>();
Map<Integer, Integer> hashmap = new HashMap<>();
Map<Integer, Integer> synchronizedHashMap = Collections.synchronizedMap(new HashMap<>());
Map<Integer, Integer> concurrentHashMap = new ConcurrentHashMap<>(); test(hashtable);
test(hashmap);
test(synchronizedHashMap);
test(concurrentHashMap);
} private static void test(Map<Integer, Integer> map) throws InterruptedException {
int testTimes = 5;
long totalTimeMillis = 0;
for (int k = 0; k < testTimes; k++) {
totalTimeMillis += costTimeMillis(map);
}
System.out.println("Test " + map.getClass() + " average time " + (totalTimeMillis / testTimes));
} private static long costTimeMillis(Map<Integer, Integer> map) throws InterruptedException {
int count = 5;
ExecutorService executorService = Executors.newFixedThreadPool(count);
long startMillis = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
executorService.execute(new Runnable() {
@Override
public void run() {
for (int j = 0; j < 500000; j++) {
map.put(0, 0);
map.get(0);
}
}
});
}
executorService.shutdown();
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
return System.currentTimeMillis() - startMillis;
}
}
输出结果如下:
Test class java.util.Hashtable average time 267
Test class java.util.HashMap average time 67
Test class java.util.Collections$SynchronizedMap average time 262
Test class java.util.concurrent.ConcurrentHashMap average time 167
Java多线程系列六——Map实现类的更多相关文章
- java多线程系列(六)---线程池原理及其使用
线程池 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java多线程系列(一)之java多线程技能 java多线程系列(二)之对象变量的并发访问 java多线程系列(三)之等待通知 ...
- java多线程系列六、线程池
一. 线程池简介 1. 线程池的概念: 线程池就是首先创建一些线程,它们的集合称为线程池. 2. 使用线程池的好处 a) 降低资源的消耗.使用线程池不用频繁的创建线程和销毁线程 b) 提高响应速度,任 ...
- Java多线程系列——线程阻塞工具类LockSupport
简述 LockSupport 是一个非常方便实用的线程阻塞工具,它可以在线程内任意位置让线程阻塞. 和 Thread.suspend()相比,它弥补了由于 resume()在前发生,导致线程无法继续执 ...
- 【Java多线程系列五】列表类
一些列表类及其特性 类 线程安全 Iterator 特性 说明 Vector 是 fail-fast 内部方法用synchronized修饰,因此执行效率较低 1. 线程安全的列表类并不意味着调用它 ...
- 【Java多线程系列六】Map实现类
Map的一些实现类有及其特性 类 线程安全 特性 Hashtable 是 Key不能为null HashMap 否 读写效率最高,但在Java6多线程环境下使用不当可能陷入死循环,进而导致CPU使用率 ...
- 【Java多线程系列二】Thread类的方法
Thread实现Runnable接口并实现了大量实用的方法. /* * 此方法释放CPU,但并不释放已获得的锁,其它就绪的线程将可能得到执行机会,它自己也有可能再次得到执行机会 */ public s ...
- (Java多线程系列六)join()的用法和线程的优先级
join()的用法和线程的优先级 1.join()的用法 join()作用就是让其他线程处于等待状态 先看一个需求:创建一个线程,子线程执行完毕后,主线程才能执行 public class JoinT ...
- Java多线程系列——从菜鸟到入门
持续更新系列. 参考自Java多线程系列目录(共43篇).<Java并发编程实战>.<实战Java高并发程序设计>.<Java并发编程的艺术>. 基础 Java多线 ...
- Java多线程系列--“JUC锁”08之 共享锁和ReentrantReadWriteLock
概要 Java的JUC(java.util.concurrent)包中的锁包括"独占锁"和"共享锁".在“Java多线程系列--“JUC锁”02之 互斥锁Ree ...
随机推荐
- LeetCode(59)SPiral Matrix II
题目 Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. F ...
- loadrunner-3个难点
1.loadrunner 监控windows资源 2.loadrunner如何实现如下: 1.1.1.1 场景一 10进程同时新增用户 测试场景说明:10进程新增用户, 第一个进程从1到1000,第二 ...
- Android BottomSheet:底部弹出Fragment面板(4)
Android BottomSheet:底部弹出Fragment面板(4) BottomSheet不仅可以弹出轻量级的定制好的面板(见附录文章5,6,7),还可以弹出"重"的 ...
- Python模块:time、datetime、random、os、sys、optparse
time模块的方法: 时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量. struct_time时间元组,共有九个元素组.如下图: time.localtime([secs]): ...
- 从零开始写STL-容器-双端队列
从零开始写STL-容器-双端队列 什么是双端队列?在介绍vector源码,我们发现在vector前端插入元素往往会引起大量元素的重新分配,双端队列(deque)就是为了解决这一问题,双端队列中在首端和 ...
- P1547 Out of Hay 洛谷
https://www.luogu.org/problem/show?pid=1547 题目背景 奶牛爱干草 题目描述 Bessie 计划调查N (2 <= N <= 2,000)个农场的 ...
- Mycat集群方案收集(待实践)
先收集,后续再实践. 我想,市面上开源方案中,涉及到高可用和负载均衡的部署,无论是哪一个产品应用,都基本离不开LVS+Keepalived+HAProxy+Nginx等等. 下面是收集的教程: htt ...
- ETL全量单表同步简述
ETL全量单表同步简述 1. 实现需求 当原数据库的表有新增.更新.删除操作时,将改动数据同步到目标库对应的数据表. 2. 设计思路 设计总体流程图如下: 注意点: 1.数据库合并时,选择正确的数据源 ...
- ip addr
ip 32 位.四个字节.IP地址分为五类,A类保留给政府机构,B类分配给中等规模的公司,C类分配给任何需要的人,D类用于组播,E类用于实验,各类可容纳的地址数目不同.A.B.C三类IP地址的特征:当 ...
- JAVA: 解决is expected to be of type but was actually of type com.sun.proxy.$Proxy的问题
修改spring-config文件中的transactionManager部分为 <tx:annotation-driven proxy-target-class="true" ...