Fork-Join
什么是分而治之?
规模为N的问题,N<阈值,直接解决,N>阈值,将N分解为K个小规模子问题,子问题互相对立,与原问题形式相同,将子问题的解合并得到原问题的解
将一个难以直接解决的大问题, 我们把它分解成一个个规格比较小的相同的问题, 方便各个击破
子问题条件(相互独立, 子问题与原问题的解决方式一样, 递归的解决小问题 后, 把小问题的解合并起来后, 得到了原问题的解)
工作密取
线程A 执行完自己的task 后, 从B 的任务队列里获取线程B 没有执行的task (从尾部获取)去执行, 执行完后把结果给B的结果队列里
好处:提高框架性能, 同时使系统资源得以完全利用
使用的标准范式
Fork/Join的同步用法同时演示返回结果值:统计整形数组中所有元素的和
单线程计算:
使用 Fork/Join:
RecursiveTask:表示我们计算任务有返回结果
RecursiveAction :没有返回结果
重写RecursiveTask 里面的compute 方法
当条件不满足时, 将task 进行拆分, 并将拆分后的task (left right) 交个invokeALL() 方法。invokeALL 会将left和right 丢给fork/join 框架, 重新去执行compute 方法, 重新去判断是否满足条件, 满足则计算, 不满足则再去拆分。拆分到最小的任务有了结果后, 通过 join 方法拿到最小单元子任务的结果,通过return 一级一级的往上一级的子任务进行提交, 当整个最外层task 运行完成后, 就拿到了整个任务的结果。join() 方法保证线程执行完
main 方法 调用时, 将总任务通过.invoke()提交给ForkJoinPool 去执行, 当整个池执行完后, 就拿到了整个任务的结果
Fork/Join 同步用法ForkJoinPool .invoke():调用线程没有获得返回结果时, 只能等待。必须等待处理结果后, 调用线程才能往下走。
异步用法, ForkJoinPool .execute() 提交完后, 调用线程可以做些自己的事情
使用多线程时,线程上下文切换需要时间, 有时候会比单线程慢
CountDownLatch
作用:允许一个或多个线程等待其他线程完成操作后, 继续自己的操作 ,加强版join
latch = new CountDownLatch(6) 参数6 表示 有几个操作完成后, 其他的线程才可以继续它的工作。
latch .countDown(); countDown负责计数器的减一, 代表还剩几个操作完成
latch .await用来等待其他线程完成工作,countDown负责计数器的减一
代码示例:
CyclicBarrier
让一组线程达到某个屏障,被阻塞,一直到组内最后一个线程达到屏障时,屏障开放,所有被阻塞的线程会继续运行CyclicBarrier(int parties)
可以在一组线程达到屏障时, 优先执行某个操作, 方便处理更复杂的业务场景
CyclicBarrier(int parties, Runnable barrierAction),屏障开放,barrierAction定义的任务会执行
CountDownLatch和CyclicBarrier辨析
1、countdownlatch放行由第三者控制,CyclicBarrier放行由一组线程本身控制
2、countdownlatch放行条件》=线程数,CyclicBarrier放行条件=线程数
Semaphore
用来控制同时访问特定资源的线程数量。 它通过协调各个线程, 以保证合理的使用公共资源
常用作流量控制, 特别是公用资源有限的应用场景。比如数据库连接池, 有界缓存等
控制同时访问某个特定资源的线程数量,用在流量控制
Exchange
用于进行线程间的数据交换, 它提供一个同步点, 在这个同步点, 两个线程可以交换彼此的数据
Callable、Future和FutureTask
Callable:线程有返回值, 并且可以抛出异常
Future:用来表示异步计算结果, 可以对具体的任务进行取消, 查询是否完成和获得任务结果
FutureTask:实现了Future 接口, 还是实现了Runnable 接口。也就是说FutureTask即可以当做一个Runnable执行, 也可以当做Future来获得Callable的运行结果。
isDone,结束,正常还是异常结束,或者自己取消,返回true;
isCancelled 任务完成前被取消,返回true;
cancel(boolean):
1、 任务还没开始,返回false
2、 任务已经启动,cancel(true),中断正在运行的任务,中断成功,返回true,cancel(false),不会去中断已经运行的任务
3、 任务已经结束,返回false
包含图片和文字的文档的处理:图片(云上),可以用future去取图片,主线程继续解析文字。