Java并发编程实战

来源:互联网 发布:mac官网 编辑:程序博客网 时间:2024/05/01 09:15

Java类库提供了丰富的并发基础构建模块

  • 同步容器类
  • 并发容器
  • 阻塞队列
  • 同步器

同步容器类
Vector, Hashtable, Collections.synchronizedXxx
1. 客户端复合操作需要加锁
2. 迭代器与ConcurrentModificationException
迭代时需要对容器加锁,或者“克隆”容器在本地变量的副本上迭代。
3. 隐形迭代器(toString, hashCode, equals, containsAll, removeAll, retainAll, 已经把容器作为参数的构造函数)

并发容器
并发容器改进了同步容器的性能。
并发容器还提供了一些原子的复合操作

ConcurrentHashMap
使用粒度更细的分段锁提高并发性和伸缩性。
返回的迭代器具有弱一致性,不是及时失败,不抛出ConcurrentModificationException异常。
额外的原子操作。

public interface ConcurrentMap<K, V> extends Map<K, V> {    V putIfAbsent(K key, V value);    boolean remove(Object key, Object value);    boolean replace(K key, V oldValue, V newValue);    V replace(K key, V value);}

CopyOnWriteArrayList (写入是复制)
在每次修改是,都会创建并发布一个新的容器的副本,从而实现可变性。
迭代器不会抛出ConcurrentModificationException异常。
每当修改容器时都会复制底层的数组,需要开销。仅当迭代操作远远多于修改操作时才使用。

阻塞队列
BlockingQueue 提供了可阻塞的put 和take方法,支持定时的offer和poll方法,可以是有界的和无界的。
ArrayBlockingQueue ->ArrayList
LinkedBlockingQueue ->LinkedList
PriorityBlockinQueue
SynchronizedQueue

适用于生产者和消费者模式
阻塞队列传递了对象的所有权。

Deque 和 BlockingDeque

BlockingQueue的阻塞方法如take()和put()方法,会抛出InterruptedException,和 Thread.sleep方法一样。
线程可以被阻塞,处于阻塞状态(BLOCKED, WAITING, TIMED_WAITING)

中断是线程间的一种协作机制,一个线程可以要求另外一个线程取消操作。
当代码中调用一个将抛出InterruptedException异常的方法时,你自己的方法就是一个阻塞方法,必须处理中断响应。有两个方式:
1. 传递InterruptedException
2. 恢复中断状态以中断当前线程

同步器
CountdownLatch闭锁
一个或者多个线程, 等待另外N个线程完成某个事情之后才能执行。如 所有人都完成跑步比赛,才宣布比赛结束。

Semaphore 信号量
限制访问同一资源的操作数量,可以实现资源池如数据库连接池,或有界阻塞容器。初始值为1的信号量,可以实现互斥锁。

CyclicBarrier栅栏
所有的线程都相互等待,直达它们都到一个栅栏点。如 所有人都到齐了才开始跑步比赛。

Exchanger

构建高效且可伸缩的结果缓存
1. 线程安全委托给底层的并发集合变量
2. 使用FutureTask处理开销很大的计算

public class Memoizer3 <A, V> implements Computable<A, V> {    private final Map<A, Future<V>> cache            = new ConcurrentHashMap<A, Future<V>>();    private final Computable<A, V> c;    public Memoizer3(Computable<A, V> c) {        this.c = c;    }    public V compute(final A arg) throws InterruptedException {        Future<V> f = cache.get(arg);        if (f == null) {            Callable<V> eval = new Callable<V>() {                public V call() throws InterruptedException {                    return c.compute(arg);                }            };            FutureTask<V> ft = new FutureTask<V>(eval);            f = ft;            cache.put(arg, ft);            ft.run(); // call to c.compute happens here        }        try {            return f.get();        } catch (ExecutionException e) {            throw LaunderThrowable.launderThrowable(e.getCause());        }    }}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 儿子14岁了不爱说话怎么办 我孩子长得老慢怎么办 老公嫌你烦了怎么办 2岁宝宝吃饭不嚼怎么办 2岁宝宝挑食厌食怎么办 孩子不爱和家长交流怎么办 孩子发烧在医院查不出病因怎么办 宝宝乳牙长歪了怎么办 两岁宝宝不爱吃水果怎么办 两岁宝宝不吃水果怎么办 一岁的宝宝上火了怎么办 吃水果嘴唇肿了怎么办 二岁宝宝不爱吃饭怎么办 小婴儿便秘但不爱喝水怎么办 宝宝只吃水果不吃饭怎么办 一岁宝宝不喜欢吃水果怎么办 1岁宝宝不吃水果怎么办 一岁半宝宝吃水果拉肚子怎么办 大人发烧了怎么办如何退烧 怀孕后不爱吃水果怎么办 不敢吃水果了怕虫怎么办 宝宝发烧38度不出汗怎么办 1岁宝宝喜欢含饭怎么办 3岁宝宝喜欢含饭怎么办 孩子咳嗽发烧怎么办最有效 孩子咳嗽打哈切流鼻涕发烧怎么办 孩子香蕉吃多了怎么办 80多岁老人发烧怎么办 小孩香蕉吃多了怎么办 7个月宝宝缺钙怎么办 宝宝脖子被汗淹到红了脱皮怎么办? 小儿出汗多咳嗽怎么办吃什么 牛高烧不退怎么办最好 猪体温低不吃食怎么办 小孩发烧咳嗽怎么办吃什么药 大晚上发烧39度怎么办 胃受凉了老打嗝怎么办 大人发低烧怎么办如何退烧 吃了退热药不退热怎么办 猪持续高烧不退怎么办 猪感冒了不吃食怎么办