hashmap和concurrenthashmap linkedhashmap的区别,concurrenthashmap和hashtable的区别
如何解决写爬虫IP受阻的问题?立即使用。
本教程运行环境:windows7系统,java10版本10,DELL G3电脑。
hashmap和concurrenthashmap的区别
HashMap是线程不安全的,多线程操作时会有安全隐患;而ConcurrentHashMap是线程安全的。
HashMap不支持并发操作,也没有同步方法。ConcurrentHashMap支持并发操作,通过继承reentrant lock(JDK 1.7 reentrant lock)/CAS和synchronized lock (JDK 1.8内置锁)实现锁(分段锁)。每个需要锁的操作都锁一个段,所以只要每个段都是线程安全的,就可以实现全局线程安全。
ConcurrentHashMap使用锁分段技术对整个Hash桶进行分段,也就是把这个大数组分成几个小段,每个小段上都有一个锁,所以在插入元素的时候,你需要找到应该先插入哪个段,然后在这个段上插入,你还需要在这里获取段锁。
ConcurrentHashMap使锁的粒度更细,并发性能更好。
(推荐教程:java入门)
HashMap
HashMap是线程不安全的,put方法没有在源代码中锁定。当释放多个线程时,会出现线程安全问题。下面是一个简单的例子来演示,创建三个线程,并启动它们。在run方法中,通过for循环在map中存储100个值,然后输出map的大小。正常情况下,地图的大小应该是100,但这里输出的是176。
类演示实现Runnable{
静态MapString,String map=new HashMap();
@覆盖
公共无效运行(){
for(int I=0;i 100i ) {
map.put(i , value );
}
}
公共静态void main(String[] args) {
新线程(新演示())。start();
新线程(新演示())。start();
新线程(新演示())。start();
//获取当前线程
thread currentThread=thread . current thread();
//当前线程休眠2秒,让上述三个线程先执行
尝试{
currentthread . sleep(2000);
} catch(异常e) {
e . getmessage();
}
//上述线程执行完毕后输出映射的大小
system . out . println(map . size());
}
}
HashTable
HashTable使用锁,它直接将锁添加到put方法中,所以线程肯定是安全的。这里,在测试线程安全性的同时,我们来看看执行时间。这里通过放10000个数据,从结果可以看出,地图的大小确实是10000,时间大概需要16ms。
类演示实现Runnable{
静态MapString,String map=new Hashtable();
@覆盖
公共无效运行(){
long start time=system . current time millis();//获取开始时间
for(int I=0;我10000;i ) {
map.put(i , value );
}
long end time=system . current time millis();//获取结束时间
system . out . println((end time-start time) ms );
}
公共静态void main(String[] args) {
新线程(新演示())。start();
新线程(新演示())。start();
新线程(新演示())。start();
//获取当前线程
thread currentThread=thread . current thread();
//当前线程休眠2秒,让上述三个线程先执行
尝试{
currentthread . sleep(2000);
} catch(异常e) {
e . getmessage();
}
//上述线程执行完毕后输出映射的大小
system . out . println(map . size());
}
}
ConcurrentHashMap
ConcurrentHashMap用的是分段锁,哪个不安全,哪个不能解锁,哪个不能完全锁,我就锁!让我们看看这个块锁对于方法锁是快还是慢。
类演示实现Runnable{
静态MapString,String map=new concurrent hashmap();
@覆盖
公共无效运行(){
长启动时间=系统。当前时间毫秒();//获取开始时间
for(int I=0;我10000;i ) {
map.put(i , value );
}
结束时间长=系统。当前时间毫秒();//获取结束时间
系统。出去。println((结束时间-开始时间) ms );
}
公共静态void main(String[] args) {
新线程(新演示())。start();
新线程(新演示())。start();
新线程(新演示())。start();
//获取当前线程
线程当前线程=线程。当前线程();
//当前线程睡眠2秒,让上面的三个线程先执行
尝试{
当前线程。睡眠(2000);
} catch(异常e) {
e。getmessage();
}
//上面的线程执行完毕后输出地图的大小
系统。出去。println(地图。size());
}
}
从结果中看到,从之前的20毫秒和22毫秒提高到了现在的17毫秒和18毫秒
更多计算机编程相关知识,请访问:编程视频!以上就是模拟和实现队列的区别是什么的详细内容,更多请关注我们其它相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。