并发编程的基本知识(二)
本章将介绍一些常用的并发工具包,主要讲大概内容,做一个引导学习的作用,想要具体看使用用法可以参考其他博客。
一、fork/join
1、概念
采用了“分而治之”的思想,将一个任务拆分成最小单远,进行处理之后,在进行合并
2、使用fork/join的标准范式
我们要使用ForkJoin框架,必须首先创建一个ForkJoin任务。它提供在任务中执行fork和join的操作机制,通常我们不直接继承ForkjoinTask类,只需要直接继承其子类。
1. RecursiveAction,用于没有返回结果的任务
2. RecursiveTask,用于有返回值的任务
task要通过ForkJoinPool来执行,使用submit 或 invoke 提交,两者的区别是:invoke是同步执行,调用之后需要等待任务完成,才能执行后面的代码;submit是异步执行。
join()和get方法当任务完成的时候返回计算结果
延伸:并归排序法就是采用了“分而治之”的思想,实现排序的效率较高
参考文档:https://blog.****.net/tyrroo/article/details/81390202
二、countdownlatch和cyclicBarrier
1、概念
countdownlatch:一个(多个)线程,必须等待其他线程执行完成后才能继续执行。
cyclicBarrier:多个线程相互等待,知道所有线程都完成,才能进行各自的后面的任务。
2、应用场景
countdownlatch:
(1)开启多个线程分块下载一个大文件,每个线程只下载固定的一截,最后由另外一个线程来拼接所有的分段。
(2)应用程序的主线程希望在负责启动框架服务的线程已经启动所有的框架服务之后再执行。
cyclicbarrier:
(1)CyclicBarrier可以用于多线程计算数据,最后合并计算结果的应用场景。
3、区别
CountDownLatch会阻塞主线程,CyclicBarrier不会阻塞主线程,只会阻塞子线程。
参考文献:https://www.cnblogs.com/liun1994/p/7396026.html
http://www.importnew.com/21889.html
三、callable
1、概念
也是实现线程的一个接口,主要用于并发编程。
2、和runnable区别和相同点
区别:
实现callable的类可以有返回值,runnable接口没有返回值
相同点:
都有方法可以阻塞主线程
四、院子操作CAS
1、概念
CAS类比于乐观锁,先执行,在进行判断是否存在多线程的争用问题。
CAS操作涉及到三个值:当前主内存中的值V,线程本地内存中的值E和待更新的值U。如果当前内存中的值V等于预期值E,则将内存中的值更新为U,CAS操作成功。否则不更新CAS操作失败,然后自旋,直到成功。流程图如下:
2、产生问题
1、ABA问题
2、消耗cpu资源
3、只保证了一个共享变量的操作
3、解决办法
1、ABA问题
加一个版本标记,比如JDK提供给我一个AtomicStampedReference就是通过对值加一个戳(stamp)来解决“ABA”问题的
2、只保证了一个共享变量的操作
JDK提供了AtomicReference类来保证引用对象之间的原子性,就可以把多个变量放在一个对象里来进行CAS操作
4.常用atomic类
最常用的就是atomicInteger,实现计数作用