Java 5.0 adds ConcurrentHashMap, a replacement for synchronized hash-based Map implementations, and CopyOnWriteArrayList, a replacement for synchronized List implementations for cases where traversal is the dominant operation. The new ConcurrentMap interface adds support for common compound actions such as put-if-absent, replace, and conditional remove.

Java 5.0 also adds two new collection types, Queue and BlockingQueue. A Queue is intended to hold a set of elements temporarily while they await processing. Several implementations are provided, including ConcurrentLinkedQueue, a traditional FIFO queue, and PriorityQueue, a (non concurrent) priority ordered queue.

Java 6 adds ConcurrentSkipListMap and ConcurrentSkipListSet, which are concurrent replacements for a synchronized SortedMap or SortedSet (such as treeMap or TReeSet wrapped with synchronizedMap).

首先我们说,替换同步hashMap的实现的concurrentHashMap,例如hashTable,写到这里突然想到了一个面试题:

在不使用锁的情况下,怎么样使hashMap 的size()方法变为线程安全的? (这个也就是要你明白ConcurrentHashMap的源码的话,就比较的容易的明白面试官要问的是什么内容)

另外还有一个比较重要的事情:

concurrentHashMap 提供的size(),isEmpty() 都是近似的精确的值,并不是完全的正确的值,这也符合并发编程环境的语意。

具体是怎么实现的,我们可以看到源码中是这样描述的:

http://www.iteye.com/topic/1103980

http://www.iteye.com/topic/344876

说的比较的详细:hashmap 被分为了segment,然后在不同的segment上面进行加锁,操作。

ConcurrentHashMap的size操作也采用了一种比较巧的方式,来尽量避免对所有的Segment都加锁。前面我们提到了一个Segment中的有一个modCount变量,代表的是对Segment中元素的数量造成影响的操作的次数,这个值只增不减,size操作就是遍历了两次Segment,每次记录Segment的modCount值,然后将两次的modCount进行比较,如果相同,则表示期间没有发生过写入操作,就将原先遍历的结果返回,如果不相同,则把这个过程再重复做一次,如果再不相同,则就需要将所有的Segment都锁住,然后一个一个遍历了。

public int size() {
// Try a few times to get accurate count. On failure due to
// continuous async changes in table, resort to locking.
final Segment<K,V>[] segments = this.segments;
int size;
boolean overflow; // true if size overflows 32 bits
long sum; // sum of modCounts
long last = 0L; // previous sum
int retries = -1; // first iteration isn't retry
try {
for (;;) {
if (retries++ == RETRIES_BEFORE_LOCK) {
for (int j = 0; j < segments.length; ++j)
ensureSegment(j).lock(); // force creation
}
sum = 0L;
size = 0;
overflow = false;
for (int j = 0; j < segments.length; ++j) {
Segment<K,V> seg = segmentAt(segments, j);
if (seg != null) {
sum += seg.modCount;
int c = seg.count;
if (c < 0 || (size += c) < 0)
overflow = true;
}
}
if (sum == last)
break;
last = sum;
}
} finally {
if (retries > RETRIES_BEFORE_LOCK) {
for (int j = 0; j < segments.length; ++j)
segmentAt(segments, j).unlock();
}
}
return overflow ? Integer.MAX_VALUE : size;
}

这个可以对应上面的那个面试题。

再说这个CopyOnWriteArray适合的场景是:CopyOnWriteArrayList适合使用在读操作远远大于写操作的场景里,比如缓存。发生修改时候做copy,新老版本分离,保证读的高性能,适用于以读为主的情况。

笔记:java并发编程实践1的更多相关文章

  1. [Java 并发] Java并发编程实践 思维导图 - 第一章 简单介绍

    阅读<Java并发编程实践>一书后整理的思维导图.

  2. [Java 并发] Java并发编程实践 思维导图 - 第二章 线程安全性

    依据<Java并发编程实践>一书整理的思维导图.

  3. 读Java并发编程实践中,向已有线程安全类添加功能--客户端加锁实现示例

    在Java并发编程实践中4.4中提到向客户端加锁的方法.此为验证示例,写的不好,但可以看出结果来. package com.blackbread.test; import java.util.Arra ...

  4. [Java 并发] Java并发编程实践 思维导图 - 第四章 对象的组合

    依据<Java并发编程实践>一书整理的思维导图. 第一部分: 第二部分:

  5. Java并发编程实践

    最近阅读了<Java并发编程实践>这本书,总结了一下几个相关的知识点. 线程安全 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任 ...

  6. java并发编程实践笔记

    文章转自:http://kenwublog.com/java-concurrency-in-practise-note 1, 保证线程安全的三种方法 :a, 不要跨线程访问共享变量b, 使共享变量是 ...

  7. 读书笔记-----Java并发编程实战(一)线程安全性

    线程安全类:在线程安全类中封装了必要的同步机制,客户端无须进一步采取同步措施 示例:一个无状态的Servlet @ThreadSafe public class StatelessFactorizer ...

  8. Java 并发编程实践基础 读书笔记: 第三章 使用 JDK 并发包构建程序

    一,JDK并发包实际上就是指java.util.concurrent包里面的那些类和接口等 主要分为以下几类: 1,原子量:2,并发集合:3,同步器:4,可重入锁:5,线程池 二,原子量 原子变量主要 ...

  9. Java 并发编程实践基础 读书笔记: 第一章 JAVA并发编程实践基础

    1.创建线程的方式: /** * StudySjms * <p> * Created by haozb on 2018/2/28. */ public class ThreadDemo e ...

随机推荐

  1. MediaPlayer+SurfaceView 视频播放 示例

    SurfaceView的原理         SurfaceView在视频播放中起到显示画面的作用,而视频的播放主要通过MediaPlayer来控制.         SurfaceView 允许我们 ...

  2. 转 - markdown 简明语法

    Markdown是一种极简的『标记语言』,将文本转为HTML,通常为我大码农所用.其不追求大而全,简洁至上,正所谓不求最贵,只求最好! 本文介绍Markdown基本语法,内容很少,一行语法一行示例,学 ...

  3. ubuntu学习笔记--不断更新中

    1.rpm软件包相关: rpm软件包安装命令: rpm -ivh linuxqq-v1.0.2-beta1.i386.rpm rpm软件默认安装路径查询: rpm -ql *.rpm ubuntu如何 ...

  4. Nginx配置域名转发实例

    域名:cps.45wan.com   所在阿里云主机:123.35.9.12 45wan没有在阿里云备案 67wan已经在阿里云备案 阿里云主机(假如123.35.9.12)上原来的nginx配置: ...

  5. RTSP协议资料

    维基百科: RTSP:http://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol RTP:http://en.wikipedia.org/wik ...

  6. mac更新之前,好容易把网络设置好

    1.[虚拟机]虚拟网络编辑器--恢复默认设置 [主机网络]自动ip [VM8] 当时忘记将mac里面的网络设置截图...导致更新后网络出问题后却显示网络设置失败

  7. 使用WebFrom来模拟一些MVC的MODEL与View的数据交互功能

    MVC中有一点非常闪瞎人眼的功能就是,可以根据Model与View视图来直接将页面也数据模型进行绑定,那么我们在想客户端发送页面时不需要进行各种控件赋值,不需要操心怎么渲染,当客户提交表单给服务器时也 ...

  8. 用Spring Boot零配置快速创建web项目(1)

    一.Spring Boot简介 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人 ...

  9. Struts2 框架验证

    struts2框架验证(xml方式):    * 首先要从页面中获取对应的标签name属性的值,在动作类action中声明同名的属性,提供get和set方法        * 创建一个xml格式验证文 ...

  10. oracle 分布式数据库

    分布式数据库的数据库链路是单向的