J.U.C包介绍

来源:互联网 发布:免费查重软件 编辑:程序博客网 时间:2024/05/22 06:06

一、包结构

1.线程池


2.同步集合

a)

BlockingQueue
ArrayBlockingQueue
LinkedBlockingQueue
PriorityBlockingQueue
DelayQueue
SynchronousQueue
ConcurrentLinkedQueue
b)
ConcurrentMap
ConcurrentHashMap
c)
CopyOnWriteArrayList
CopyOnWriteArraySet
d)
CountDownLatch
CyclicBarrier
Exchanger
Semaphore

 


3.锁

J.U.C的locks包


4.原子操作

J.U.C的atomic包中的类
(1)计数器:AtomicBoolean, AtomicInteger, AtomicLong
(2)域更新器(基于反射,用于已有类的volatile域的更新):AtomicIntegerFieldUpdater, AtomicLongFieldUpdater, AtomicReferenceFieldUpdater
(3)数组:AtomicIntegerArray, AtomicLongArray, AtomicReferenceArray
(4)引用:AtomicReference, AtomicStampedReference, AtomicMarkableReference
5.辅助类

(1)CancellationException
(2)ExecutionException
(3)TimeoutException
(4)RejectedExecutionException
(5)TimeUnit
(6)BrokenBarrierException


二、J.U.C中锁和内部锁比较

1.内部锁synchronized、wait、notify/notifyAll
2.J.U.C中锁Lock、Condition
3.比较
(1)三要素:锁、条件、等待队列
(2)锁:synchronized vs Lock
(3)条件:wait, notify/notifyAll vs Condition.await, signal/signalAll
(4)等待队列:锁对象 vs Condition
4.J.U.C中锁优劣
(1)优:一个锁上可以有多个条件及等待队列;性能好;
(2)劣:不易用,容易出错(如:未在finally中写lock.unlock)


三、类功能一览

1.ThreadPoolExecutor

(1)构造函数:ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)

(2)参数解释

corePoolSize:核心池大小

maximumPoolSize:池最大大小

keepAliveTime:无工作线程的存活时间

unit:时间的单位

workQueue:保持任务的队列

threadFactory:用于创建线程的工厂

handler:拒绝执行的处理类

(3)内部逻辑
初始时,由于线程数未达到corePoolSize,所以线程数不断增加,用来处理任务;当达到corePoolSize时,会将任务放入workQueue中;如果workQueue也满了,那么再次添加线程处理任务,直到线程数为maximumPoolSize;如果此时再有任务提交,就会调用reject来进行相应的处理;当线程空闲时,会根据keepAliveTime进行线程回收
(4)四种拒绝策略
CallerRunsPolicy:由调用者线程来处理任务
AbortPolicy:直接抛出RejectedExecutionException
DiscardPolicy:不执行任务,直接抛弃
DiscardOldestPolicy:移除任务队列的头任务

2.Executors

(1)生成ExecutorService的工厂类
(2)newSingleThreadExecutor() :corePoolSize=maximumPoolSize=1,workQueue=LinkedBlockingQueue(容量是Integer.MAX_VALUE)
(3)newCachedThreadPool():corePoolSize=0,maximumPoolSize=Integer.MAX_VALUE,keepAliveTime=60s,workQueue=SynchronousQueue(容量是0)
(4)newFixedThreadPool(int nThreads):corePoolSize=maximumPoolSize=nThreads,keepAliveTime=0,workQueue=LinkedBlockingQueue(容量是Integer.MAX_VALUE)
(5)newSingleThreadScheduledExecutor():单线程,延迟执行任务
(6)newScheduledThreadPool(int corePoolSize):corePoolSize,maximum=Integer.MAX_VALUE,keepAliveTime=0,workQueue=DelayedWorkQueue

3.Future,FutureTask

(1)FutureTask实现Future
(2)表示一个在线程池中执行任务的返回结果
(3)AbstractExecutorService的newTaskFor方法
(4)Future
   a)cancel 取消执行
   b)get 取结果

 

4.ReentrantLock

(1)可重入锁:在同一个线程内,可以进行任意次数的加锁
(2)方法:lock、unlock、tryLock、newCondition
(3)公平锁、非公平锁


5.Condition

await、signal、signalAll


6.ReentrantReadWriteLock

(1)读写分离
(2)readLock
(3)writeLock
(4)读锁不可升级
   a)错误方式:readLock.lock,writeLock.lock,死锁
   b)正确方式:readLock.lock,readLock.unlock,writeLock.lock
(5)写锁可降级
   a)writeLock.lock,readLock.lock,writeLock.unlock,降级为读锁

 

7.AtomicInteger

(1)compareAndSet
(2)incrementAndGet
(3)decrementAndGet
(4)……
(5)可用于计数器之类的用途

 

8.AtomicReferenceFieldUpdater

(1)static newUpdater(Class<U> tclass, Class<W> vclass, String fieldName)
   a)tclass 对象类
   b)vclass 域类
   c)fieldName 域名
(2)用于已有类的volatile域的原子更新
(3)代码

 

9.ArrayBlockingQueue

(1)锁条件
   a)notEmpty
   b)notFull
(2)方法
   a)put:notFull.await, notEmpty.singal
   b)take:notEmpty.await, notFull.singal
   c)offer(阻塞或不阻塞): notFull.await, notEmpty.singal
   d)poll (阻塞或不阻塞) : notEmpty.await, notFull.singal

10.ConcurrentHashMap

(1)实现方式
   a)将ConcurrentMap分为许多个segment,每个segment其实就相当于一个普通的Map(HashMap实现:通过hash算法先找到在数组的哪个位置,如果冲突,利用链表方式解决冲突)
   b)计算key的hash值,将其分到一个segment上,获取这个segment的锁,然后再对这个segment进行更新
   c)默认为16个segment
(2)增加了几个方法,如:V putIfAbsent(K key, V value);

 

11.CopyOnWriteArrayList

(1)适用于大量读,少量写的情况
(2)实现
   a)内部使用了ReentrantLock
   b)当对其修改时,加锁,复制整个底层数组,并进行修改,最后切换底层数组引用

12.Semaphore

(1)信号量的实现
(2)方法
   a)构造函数(int permits)
   b)acquire(int permits):得到许可
   c)release(int permits):释放许可
   d)tryAcquire(int permits)
(3)主要用于池技术

 

13.CountDownLatch

(1)方法
   a)构造函数(int count)
   b)countDown
   c)await
   d)count减到0时,await通过

(2)代码

 

14.CyclicBarrier

(1)一组线程互相等待,直到某个屏障点

(2)方法
   a)CyclicBarrier(int parties)
   b)CyclicBarrier(int parties, Runnable barrierAction)
   c)await
   d)reset:重置到初始值,可重复使用
   e)await的线程数量到parties时,所有线程共同通过await,但只由最后一个线程执行barrierAction

 

四、锁、非阻塞算法和CAS

1.比较
(1)锁:悲观策略;需要上下文切换
(2)非阻塞算法:乐观策略;冲突检测,硬件支持;自旋等待,不需要上下文切换;高并发下,资源竞争过于激烈
2.CAS (compare and set)
(1)原理:内存值V,旧值A,新值B;当V==A时,才将内存值更新为B;否则,在循环中重试,直到成功为止
(2)J.U.C中atomic包的类实现了CAS的操作

3.atomic包中的类
(1)计数器:AtomicBoolean, AtomicInteger, AtomicLong
(2)域更新器(基于反射,用于已有类的volatile域的更新):AtomicIntegerFieldUpdater, AtomicLongFieldUpdater, AtomicReferenceFieldUpdater
(3)数组:AtomicIntegerArray, AtomicLongArray, AtomicReferenceArray
(4)引用:AtomicReference, AtomicStampedReference, AtomicMarkableReference


五、线程活跃度

1.死锁
(1)锁顺序不一致造成
(2)工具:jconsole,jstack
2.饥饿
(1)AQS中锁
   a)公平锁(必须进入等待队列)
   b)非公平锁(可以不进入等待队列)(吞吐量大,性能好)
3.活锁
(1)不正确的重试,而且不断重试(将不可修复的错误当成可修复的错误)

六、提升多线程性能的方法

1.减小锁的范围:使同步块尽可能的小
2.减小锁的粒度
(1)分拆锁:如果一个锁用于几个用途,则将其分拆成几个不同的锁
(2)分离锁:一个锁,再分成不同的部分(如:ConcurrentHashMap就分成了16锁,从而减少冲突的可能性)
3.减少上下文切换
(1)启动适当的线程数
(2)锁-->非阻塞

 

七、多线程性能测试
1.垃圾回收
(1)保证垃圾回收在运行期间执行多次,测试时间更长
(2)查看gc日志:-verbose:gc -Xloggc:/tmp/gc.log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps,确保测试期间gc多次运行
2.动态编译
(1)代码可能以字节码解释执行;当某部分代码运行多次后,编译为机器码,直接执行
(2)让代码首先”warm up”,即调用被测方法达到一定次数,然后再测试被测方法
(3)次数确定,-XX:+PrintCompilation开关,来查看某一方法在调用多少次后被编译,修改程序再次运行测试
3.代码路径:确保测试的代码路径和真实情况一致
4.竞争程度:确保测试的竞争程度和真实情况一致
5.dead code
(1)编译器会优化代码,从而消除一些你认为会执行的代码,这些代码对结果没有任何影响
(2)可以加入类似于System.out.print()这样的代码来防止编译器优化掉你的代码(会增加一点点性能开销,不会增加IO开销,因为在调用System.out.println时才产生IO操作)


6.静态代码分析工具(除错,findbugs)

原创粉丝点击