(一)并发工具
1,fork-join框架;fork-join采用分而治之的思想,即规模为N的问题,N<阈值,直接解决,N>阈值,将N分解为K个小规模子问题,子问题互相对立,与原问题形式相同,将子问题的解合并得到原问题的解。实现了工作密取即当一个线程完成任务后会分担没有完成任务的线程的任务。当两个线程共同完成一个任务时,两个线程拿任务一个从头拿,一个从未拿 所以不会有竞争。
使用:通过实现RecursiveTask、RecursiveAtion、ForkJoinTask的compute方法使用,而ForkJoinTask时其他两个抽象类的父类
2,cyclibarriar和countDownlatch的区别
countDownlatch一般是一个线程等待若干个线程完成后再执行;cycbarriar是一组线程等到该组线程多到达某个点后一起执行
(二)阻塞队列
1,ArrayBlockingQueue:一个由数组构成的有界阻塞队列,按照先进先出的原则,要求必须要设定初始值,只是用了一个锁
2,LinkBlockingQueue:一个由链表组成的有界阻塞队列,按照先进先出的原则,不要要求必须要设定初始值,只是用了两个锁
3,priorityBolckingQueue:一个支持有优先级排序的无界阻塞队列,默认自然排序,除非实现compareto()方法
4,DelayQueue:一个使用支持优先级队列实现的无界阻塞队列,可实现延迟获取元素的队列,元素必须要实现delayed接口;使用场景:订单到期,现时支付
5,synchronizedQueue:一个不存储元素的队列;每一个put都要等待一个take操作
6,LinkedTransferQueue:一个由链表结构组成的无界阻塞队列
7,LinkedBlockingDeque:一个由链表组成的双向阻塞队列,可以从头、尾插入或者移除元素,实现工作觅取
(三)线程池
1,线程池的作用
1>降低线程创建、销毁的的资源消耗
2>提高线程的可管理性
2,线程池的创建
ExecutorService pool = new ThreadPoolExecutor(2,4,3,TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(10),
new ThreadPoolExecutor.DiscardOldestPolicy());
1>int corePoolSize :线程池中核心线程数,< corePoolSize ,就会创建新线 程,= corePoolSize ,这个任务就会保存到BlockingQueue,如果调用 prestartAllCoreThreads()方法就会一次性的启动corePoolSize 个数的线程。
2>int maximumPoolSize, 允许的最大线程数,BlockingQueue也满了,< maximumPoolSize时候就会再次创建新的线程
3>long keepAliveTime, 线程空闲下来后,存活的时间,这个参数只在> corePoolSize 才有用TimeUnit unit, 存活时间的单位值
4>BlockingQueue<Runnable> workQueue, 保存任务的阻塞队列
5>hreadFactory threadFactory, 创建线程的工厂,给新建的线程赋予名字
6>RejectedExecutionHandler handler :饱和策略
AbortPolicy :直接抛出异常,默认;
CallerRunsPolicy:用调用者所在的线程来执行任务
DiscardOldestPolicy:丢弃阻塞队列里最老的任务,队列里最靠前的任务
DiscardPolicy :当前任务直接丢弃
实现自己的饱和策略,实现RejectedExecutionHandler接口即可
3,预定义的线程池
1>FixedthreadPool:创建了一个固定线程的线程池,使用了无界队列
2>SingleThreadExecutor:创建单个线程,使用了无界队列
3>cachedThreadPool:会根据需要来创建新线程的,执行很多短期异步任务的程序,使用了SynchronousQueue。创建线程过多时会把服务器弄垮
4>WorkStealingPool(JDK7以后):基于ForkJoinPool实现,工作觅取线程池
(四)怎样才能做到线程安全
1、栈封闭
方法内部定义的变量,都是处于栈封闭状态,线程是安全的
2、无状态
没有任何成员变量的类,叫做无状态类
3、让状态(成员变量)不可变
1,通过在成员变量之前加上final,使得成员变量不可修改
2,根本不提供任何修改成员变量的机会,成员变量也不作为方法的返回值
4、volatile
保持了成员变量的可见性和有序性
5、加锁、CAS
6、安全的发布
类中持有的成员变量,特别是对象的引用,如果这个成员对象是线程不安全的,那 么当它通过get方法发布出去的时候,会造成这个成员对象在多线程下不正确的修改, 导致线程安全问题
7、ThreadLocal