笔记:java并发编程实践1
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的更多相关文章
- [Java 并发] Java并发编程实践 思维导图 - 第一章 简单介绍
阅读<Java并发编程实践>一书后整理的思维导图.
- [Java 并发] Java并发编程实践 思维导图 - 第二章 线程安全性
依据<Java并发编程实践>一书整理的思维导图.
- 读Java并发编程实践中,向已有线程安全类添加功能--客户端加锁实现示例
在Java并发编程实践中4.4中提到向客户端加锁的方法.此为验证示例,写的不好,但可以看出结果来. package com.blackbread.test; import java.util.Arra ...
- [Java 并发] Java并发编程实践 思维导图 - 第四章 对象的组合
依据<Java并发编程实践>一书整理的思维导图. 第一部分: 第二部分:
- Java并发编程实践
最近阅读了<Java并发编程实践>这本书,总结了一下几个相关的知识点. 线程安全 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任 ...
- java并发编程实践笔记
文章转自:http://kenwublog.com/java-concurrency-in-practise-note 1, 保证线程安全的三种方法 :a, 不要跨线程访问共享变量b, 使共享变量是 ...
- 读书笔记-----Java并发编程实战(一)线程安全性
线程安全类:在线程安全类中封装了必要的同步机制,客户端无须进一步采取同步措施 示例:一个无状态的Servlet @ThreadSafe public class StatelessFactorizer ...
- Java 并发编程实践基础 读书笔记: 第三章 使用 JDK 并发包构建程序
一,JDK并发包实际上就是指java.util.concurrent包里面的那些类和接口等 主要分为以下几类: 1,原子量:2,并发集合:3,同步器:4,可重入锁:5,线程池 二,原子量 原子变量主要 ...
- Java 并发编程实践基础 读书笔记: 第一章 JAVA并发编程实践基础
1.创建线程的方式: /** * StudySjms * <p> * Created by haozb on 2018/2/28. */ public class ThreadDemo e ...
随机推荐
- Scrapy开发
最近要开发一个软件需要爬取网站信息,于是选择了python 和scrapy下面做一下简单介绍:Scrapy安装连接,scrapy官网连接 所谓网络爬虫,就是一个在网上到处或定向抓取数据的程序,当然,这 ...
- MaterialDialog的用法:
MaterialDialog的用法:/** * * @author smiling * @date 2016/10 */ Github:https://github.com/drakeet/Mater ...
- webpy:页面下载的三种实现方式
python: 1.import urllib urlretrieve() 方法直接将远程数据下载到本地. >>> help(urllib.urlretrieve)Help on f ...
- C#_DBHelper_SQL数据库操作类.
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Data; ...
- XML数据的读取—数据库配置文件
数据库配置文件(config.xml) <?xml version="1.0" encoding="utf-8"?> <configurati ...
- How to Build CyanogenMod for One X (codename: endeavoru)
来源:http://wiki.cyanogenmod.org/w/Build_for_endeavoru#What_you.E2.80.99ll_need How to Build CyanogenM ...
- csms发布步骤
1.wcf发布 通过点击 CSMS2.Application,右键发布按钮,将文件拷贝 2.打包文件 CSMS2.Resources 中 update.config 修改为对应 ServerUrl地址 ...
- JDBC连接Oracle数据库时出现的ORA-12505错误及解决办法
转载至http://www.blogjava.net/itspy/archive/2007/12/20/169072.html Oracle 问题描述:今天使用jdbc连接oracle 10.2.0. ...
- jQuery ui 利用 datepicker插件实现开始日期(minDate)和结束日期(maxDate)
这篇文章主要介绍了jQuery ui 利用 datepicker插件实现开始日期(minDate)和结束日期(maxDate),需要的朋友可以参考下 使用jQuery ui首先需要引入jQuery类库 ...
- hdu 2480 贪心+简单并查集
Steal the Treasure Time Limit: 10000/6000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...