(1)背景
简单地说,就是如果说有一组任务的话,我们可以使用线程池,并发执行这些任务就可以提高运行效率了
但是,现在只有一个任务,而且这个任务可以拆分为一组不相关的子任务,这时就可以使用Fork/Join框架了
举个例子:
1.有50个1+2+..+100的任务
使用ThreadPool执行这50个任务即可
2.仅有1个1+2+..+100的任务
一般情况下就用一个线程执行就可以了,但是我们为了提高效率,可以将这个任务拆分为1+2,3+4....99+100这50个任务,对这50个任务并发执行,之后再将这50个结果合并就可以提高效率
实际上就是算法中的分治
再次提醒:Task 0只是一个任务
(2)设计要点
1.工作窃取算法1)基本思想
也就是如果某个线程先执行完了,那么就会从其他任务队列中偷取任务过来帮助执行
2)使用工作窃取算法原因
<1>假如当前要执行一个比较大的任务,我们通过分治将这个任务分割为一组互不依赖的子任务。
<2>为了减少线程间的竞争(如果只使用一个队列,那么各个线程从队列中取任务的时候不可避免的会有竞争),于是将这些子任务分别放到不同的队列中,并为每一个队列创建一个线程来执行这个队列中的任务。这里队列和线程是一一对应的
<3>但是有的线程会先执行完自己队列中的任务,而其他线程还有任务没有完成。因为需要等待全部任务完成再将最终结果合并,所以做完任务的线程只能等着
<4> 但是干完任务的线程与其等着,还不如去帮其他线程干活,所以它就会从其他线程的队列中窃取一个任务来执行
<5>因为在窃取过程中会有2个线程访问同一个任务队列,所以必然会有竞争,这时候可以将任务队列设置成双向队列,队列对应的线程按照队列规则从头部拿任务,窃取线程从队尾拿
3)缺点
<1>当双向队列中只有一个任务的时候,仍然会出现竞争
<2>因为创建了多个线程多个队列,因而会消耗更多资源