java多线程 -- ConcurrentHashMap 锁分段 机制
hashtable效率低
ConcurrentHashMap 线程安全,效率高
Java 5.0 在 java.util.concurrent 包中提供了多种并发容器类来改进同步容器 的性能。
- ConcurrentHashMap 同步容器类是Java 5 增加的一个线程安全的哈希表。对 与多线程的操作,介于 HashMap 与 Hashtable 之间。内部采用“锁分段”机制替代 Hashtable 的独占锁。进而提高性能。
- 此包还提供了设计用于多线程上下文中的 Collection 实现:ConcurrentHashMap、ConcurrentSkipListMap、ConcurrentSkipListSet、CopyOnWriteArrayList 和 CopyOnWriteArraySet。当期望许多线程访问一个给 定 collection 时,ConcurrentHashMap 通常优于同步的 HashMap,ConcurrentSkipListMap 通常优于同步的 TreeMap。当期望的读数和遍历远远 大于列表的更新数时,CopyOnWriteArrayList 优于同步的 ArrayList。
关于锁分段机制:
HashTable容器在竞争激烈的并发环境下表现出效率低下的原因是所有访问HashTable的线程都必须竞争同一把锁,假如容器里有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效提高并发访问效率,这就是ConcurrentHashMap所使用的锁分段技术。首先将数据分成一段一段地存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问

Segment是一种可重入锁(ReentrantLock),在ConcurrentHashMap里扮演锁的角色;
HashEntry则用于存储键值对数据;
--引自 《java并发编程的艺术》
ConcurrentHashMap 和HashMap方法基本上保持一致。
当多线程访问并处理List的时候会出现并发修改异常:
Exception in thread "Thread-8" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:)
at java.util.ArrayList$Itr.next(ArrayList.java:)
at com.company.HelloThread.run(TestCopyOnWriteArrayList.java:)
at java.lang.Thread.run(Thread.java:)
Exception in thread "Thread-7" Exception in thread "Thread-9" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:)
at java.util.ArrayList$Itr.next(ArrayList.java:)
at com.company.HelloThread.run(TestCopyOnWriteArrayList.java:)
at java.lang.Thread.run(Thread.java:)
出现这种情况demo:
package com.company; import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List; public class TestCopyOnWriteArrayList { public static void main(String[] args) {
HelloThread ht = new HelloThread(); for (int i = 0; i < 10; i++) {
new Thread(ht).start();
}
} } class HelloThread implements Runnable { private static List<String> list = Collections.synchronizedList(new ArrayList<String>()); static {
list.add("小王");
list.add("中王");
list.add("大王");
} @Override
public void run() { Iterator<String> it = list.iterator(); while (it.hasNext()) {
System.out.println(it.next()); list.add("==");
} } }
那么如果避免多线程下这种问题的产生呢,利用CopyOnWriteArrayList :
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList; /*
* CopyOnWriteArrayList/CopyOnWriteArraySet : “写入并复制”
* 注意:添加操作多时,效率低,因为每次添加时都会进行复制,开销非常的大。并发迭代操作多时可以选择。
*/
public class TestCopyOnWriteArrayList { public static void main(String[] args) {
HelloThread ht = new HelloThread(); for (int i = 0; i < 10; i++) {
new Thread(ht).start();
}
} } class HelloThread implements Runnable { // private static List<String> list = Collections.synchronizedList(new ArrayList<String>()); private static CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); static {
list.add("大王A");
list.add("大王B");
list.add("大王C");
} @Override
public void run() { Iterator<String> it = list.iterator(); while (it.hasNext()) {
System.out.println(it.next()); list.add("====");
} } }
结果:
大王A
大王A
大王A
大王B
大王A
大王B
大王A
大王B
大王C
大王A
大王A
大王B
大王C
====
大王C
大王B
大王B
大王C
====
大王A
大王C
====
大王A
====
====
大王B
大王C
====
大王B
大王A
====
大王C
====
====
====
大王B
大王C
====
====
大王B
====
====
====
====
大王C
====
====
====
====
====
大王C
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
java多线程 -- ConcurrentHashMap 锁分段 机制的更多相关文章
- 3.ConcurrentHashMap 锁分段机制 Copy-On-Write
/*ConcurrentHashMap*/ Java 5.0 在 java.util.concurrent 包中提供了 多种 并发容器来改进同步容器的性能 ConcurrentHashMap 同步容器 ...
- 四、ConcurrentHashMap 锁分段机制
回顾: HashMap与Hashtable的底层都是哈希表,但是 HashMap:线程不安全 Hashtable:线程安全,但是效率非常低,且存在[复合操作](如"若存在则删除") ...
- JAVA多线程与锁机制
JAVA多线程与锁机制 1 关于Synchronized和lock synchronized是Java的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码 ...
- 3、JUC--ConcurrentHashMap 锁分段机制
ConcurrentHashMap Java 5.0 在 java.util.concurrent 包中提供了多种并发容器类来改进同步容器的性能. ConcurrentHashMap 同步容器 ...
- Java 多线程:锁(三)
Java 多线程:锁(三) 作者:Grey 原文地址: 博客园:Java 多线程:锁(三) CSDN:Java 多线程:锁(三) StampedLock StampedLock其实是对读写锁的一种改进 ...
- Java 多线程:锁(一)
Java 多线程:锁(一) 作者:Grey 原文地址: 博客园:Java 多线程:锁(一) CSDN:Java 多线程:锁(一) CAS 比较与交换的意思 举个例子,内存有个值是 3,如果用 Java ...
- Java 多线程:锁(二)
Java 多线程:锁(二) 作者:Grey 原文地址: 博客园:Java 多线程:锁(二) CSDN:Java 多线程:锁(二) AtomicLong VS LongAddr VS Synchroni ...
- Java多线程系列——锁的那些事
引入 Java提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率. 下面先带大家来总体预览一下锁的分类图 java锁的具体实现类 1.乐观锁 VS 悲观锁 乐观锁与悲观锁是 ...
- ConcurrentHashMap(锁分段技术)
线程不安全的HashMap 因为多线程环境下,使用Hashmap进行put操作会引起死循环,导致CPU利用率接近100%,所以在并发情况下不能使用HashMap. 效率低下的HashTab ...
随机推荐
- 【Unity Shader】渲染管线
流程概述 应用程序阶段 应用程序阶段,使用高级编程语言(C.C++.JAVA 等)进行开发,主要和CPU.内存打交道,诸如碰撞检测.场景图建立.空间八叉树更新.视锥裁剪等经典算法都在此阶段执行.在该阶 ...
- 企业服务总线ESB
# 企业服务总线ESB 由中间件技术实现并支持SOA的一组基础架构,支持异构环境中的服务.消息以及基于事件的交互,并且具有适当的服务级别和可管理性. 通过使用ESB,可以在几乎不更改代码的情况下,以一 ...
- java.io.tmpdir指定的路径在哪?
Java.io.tmpdir介绍 System.getproperty(“java.io.tmpdir”)是获取操作系统缓存的临时目录,不同操作系统的缓存临时目录不一样, 在Windows的缓存目录为 ...
- JS模块化样例
var fn_pageBtn = (function(){ var m1 = function(){ alert(1); }; var m2 = function(){ alert(2); }; re ...
- Daily Scrumming* 2015.10.31(Day 12)
一.今明两天任务表 Member Today’s Task Tomorrow’s Task 江昊 学习rails的HTTP控制 继续学习rails等项目工具 杨墨犁 学习semanticUI的用法,配 ...
- [BUAA OO]第二次博客作业
第五次作业 这次作业是电梯系列作业的终极版,要求是使用多线程实现三部电梯的运行.这次作业的难点在于第一次运用多线程技术,对于线程中的行为并不了解,以及电梯功能的实现(如果之前作业采取的是扫描指令队列预 ...
- 20162314 Experiment 1: Linear structure - experiment report.
Experiment report of Besti course:<Program Design & Data Structures> Class: 1623 Student N ...
- 项目Beta冲刺(团队)第三天
1.昨天的困难 记住密码打勾之后点击登录记住密码这四个字会变成省略号 点赞点击以后本应该呈现的爱心形状变成了方块 2.今天解决的进度 成员 进度 陈家权 私信模块探索ing,回复详情界面设计 赖晓连 ...
- ubuntu安装php-curl拓展
首先输入apt-cache search curl | grep php查询curl的php支持名字可能会返回如下内容:php5-curl - CURL module for php5安装:sudo ...
- angularJS1笔记-(9)-自定义指令(restrict/template/replace)
index.html: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...