码迷,mamicode.com
首页 > 编程语言 > 详细

笔记:java并发编程实践1

时间:2014-12-09 00:24:05      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   ar   color   使用   sp   for   

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的源码的话,就比较的容易的明白面试官要问的是什么内容)

bubuko.com,布布扣

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

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

bubuko.com,布布扣

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

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

标签:style   blog   http   io   ar   color   使用   sp   for   

原文地址:http://www.cnblogs.com/zhailzh/p/4152251.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!