Fork/Join框架之双端队列
来源:互联网 发布:手机怎么设置4g网络 编辑:程序博客网 时间:2024/05/16 08:31
简介
ForkJoinPool管理着ForkJoinWorkerThread线程,ForkJoinWorkerThread线程内部有一个双端队列,这个双端队列主要由一个数组queue、数组下标queueBase、数组上标queueTop三个值保证。
ForkJoinTask<?>[] queue:数组的大小必须是2的n次方,方便将取模转换为移位运算;
int queueTop:标识下一个被push或者pop的位置,这个值只会被当前线程修改,因些没有加volatile修饰;
volatile int queueBase:下一个可以被其他线程steal的位置,由于其他线程会修改这个值,所以用volatile修饰保证可见性。
初始化
在线程的run方法启动时,会调用线程的onStart()方法,在这个方法中对queue进行了初始化,长度为1 << 13,这个方法并没有对queueTop,queueBase进行赋值,采用默认值0。
扩容
当向线程中添加任务时,有可能会导致数组满的情况,如下代码所示:
其中s代表queueTop的值,m为数组长度-1,当s == m时,也就是queue数组中都放满任务了,这时需要对数组进行扩容。
从以上扩容代码可以看出,最大容量不能超过MAXIMUM_QUEUE_CAPACITY(1 << 24),最小不能小于初始值。每次扩容为先前大小的2倍,将原始数组复制到新数组中,同时将旧数组置null。扩容的过程中,queueBase和queueTop并不需要变化。
入队列
向线程队列中添加一个任务,或者向线程池添加一个任务时,如果这个任务是一个ForkJoinTask实例,就会做入队列的操作。前面已有这段代码,这里简要分析一下
第一行,找到queueTop在数组中的位置
第二行,用新任务填充queueTop所在位置
第三行,queueTop加1.
出队列
本地线程需要执行一个任务
注意locallyFifo 这个属性,是否对自己的队列采用FIFO策略,默认为false,即默认从queueTop一端取任务。如果这个值为false,则从queueBase一端取数据。这个值可以通过ForkJoinPool类的asyncMode属性加以修改。关键两句话:
queueBase = b + 1:FIFO策略每次从queueBase取任务,每取一个,queueBase增加1;
--s,queueTop = s:LIFO策略每次从queueTop取任务,每取一个,queueTop减1。
其他线程需要偷一个任务执行
以下是work-stealing的核心代码
1、瞄到第i个位置这个任务,i = (q.length-1) & b,i其实就是queueBase在数组中所在的位置;
2、将这个位置上的任务设置为null,并增加queueBase的值,设置stealHint表示你的东西被我偷了;
3、保存先前的currentSteal值,设置currentSteal为这个偷来的task,然后执行这个task,执行完后,恢复currentSteal的值。
- Fork/Join框架之双端队列
- Fork/Join框架之双端队列
- Fork/Join框架之Fork、Join操作
- Fork/Join框架之Fork、Join操作
- Fork/Join框架之Fork、Join操作
- Fork/join框架之ForkJoinPool
- Fork/join框架之ForkJoinPool
- Java线程之fork/join框架
- 并行编程之Fork/Join框架
- Java多线程之fork/join框架详解
- JDK7新特性之fork/join框架
- java并发 java7之fork-join框架
- java并发之Fork/Join框架
- Java多线程之fork/join框架详解
- Java线程之fork/join框架
- Java并发之Fork-Join框架
- Fork/Join框架介绍
- Fork/Join框架介绍
- C#HttpClient或使用CookieContainer模拟登陆后HttpRequest不发送cookie的解决方法及原因
- 图文并茂用地址分析双向链表
- robot framework 自定义关键字详细过程及debug。
- 文件较复杂操作: 打包、解压
- [Java]知乎下巴第0集:让我们一起来做一个知乎爬虫吧哦耶
- Fork/Join框架之双端队列
- c预处理命令
- QSignalMapper 使用方法 参见QSignalMapper中使用文档
- Dubbo-----HelloWorld之Zookeeper注册中心(2)
- Thread代替引用传递,利用ThreadLocal来为每一个线程保留自己的空间
- aidl is missing 错误解决方法
- 多维随机变量与其对应的分布
- [Java]知乎下巴第2集:使用爬虫来获取知乎的编辑推荐内容
- axis2发布webservice