并发编程--并发阶段任务的运行
2014-09-08 09:34
183 查看
java并发Api提供了一个更复杂、更强大的同步辅助类,即Phaser,它允许执行并发多阶段任务。当我们有并发任务并且需要分解成几步执行时,这种机制就非常适用。Phaser类机制是在每一步结束的位置对线程进行同步,当所有的线程完成了这一步,才允许执行下一步。
跟其他同步工具一样,必须对Phaser类中参与同步操作的任务数进行初始化,不同的是,我们可以动态地增加或者减少任务数。
下面例子是查矩阵包含某元素的个数,我们分别启动3个线程,每个线程计算该矩阵一行包含某元素的个数,这个过程分成两个阶段,第一个阶段是获得该矩阵的行,第二阶段是计算该行包含某元素的个数,三个线程在并发执行每个阶段进行同步,然后把结果放在线程共享变量LinkList中
![](https://img-blog.csdn.net/20140908095407281?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ3VvemVoYW81MjA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20140908095651983?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ3VvemVoYW81MjA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20140908095445796?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ3VvemVoYW81MjA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20140908095705976?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ3VvemVoYW81MjA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
启动线程thread0,thread1,thread2后,三个线程执行run先执行getRow方法,getRow方法内部使用了Phaser.arriveAndAwaitAdvance(),保证了三个线程同步开始执行getRow方法,在同一个起跑线上,然后再执行filterRow方法,过滤出某行包含某元素的个数,同样使用了Phaser.arriveAndAwaitAdvance(),先执行到该阶段的线程先等待其他线程到达该阶段,然后再一起执行,如果某个线程在搜素矩阵某行发现没有某元素,就调用Phaser.arriveAndDeregister()方法,顾名思义,就是某线程到达某种结果或者某个阶段(这里就是没有搜索到某元素),就解除注册在Phaser中的线程,这时候Phaser的计数器会减一,在下一次调用Phaser.arriveAndAwaitAdvance()时,它就知道只需要再等待多少个线程到达才开始执行下一阶段。
自己也可以编写自定义的Phaser,只要继承Phaser类,同时可以覆盖Phaser类的方法,比如覆盖onAdvance方法,在线程在每个阶段切换的时候执行onAdvance方法相关的代码。这个很实用。
跟其他同步工具一样,必须对Phaser类中参与同步操作的任务数进行初始化,不同的是,我们可以动态地增加或者减少任务数。
下面例子是查矩阵包含某元素的个数,我们分别启动3个线程,每个线程计算该矩阵一行包含某元素的个数,这个过程分成两个阶段,第一个阶段是获得该矩阵的行,第二阶段是计算该行包含某元素的个数,三个线程在并发执行每个阶段进行同步,然后把结果放在线程共享变量LinkList中
启动线程thread0,thread1,thread2后,三个线程执行run先执行getRow方法,getRow方法内部使用了Phaser.arriveAndAwaitAdvance(),保证了三个线程同步开始执行getRow方法,在同一个起跑线上,然后再执行filterRow方法,过滤出某行包含某元素的个数,同样使用了Phaser.arriveAndAwaitAdvance(),先执行到该阶段的线程先等待其他线程到达该阶段,然后再一起执行,如果某个线程在搜素矩阵某行发现没有某元素,就调用Phaser.arriveAndDeregister()方法,顾名思义,就是某线程到达某种结果或者某个阶段(这里就是没有搜索到某元素),就解除注册在Phaser中的线程,这时候Phaser的计数器会减一,在下一次调用Phaser.arriveAndAwaitAdvance()时,它就知道只需要再等待多少个线程到达才开始执行下一阶段。
自己也可以编写自定义的Phaser,只要继承Phaser类,同时可以覆盖Phaser类的方法,比如覆盖onAdvance方法,在线程在每个阶段切换的时候执行onAdvance方法相关的代码。这个很实用。
相关文章推荐
- Java7并发编程--3.4、Phaser并发阶段任务的运行
- JAVA 并发编程随笔【五】Thread线程创建及运行线程任务
- JAVA 并发编程随笔【五】Thread线程创建及运行线程任务
- JAVA 并发编程随笔【五】Thread线程创建及运行线程任务
- JAVA 并发编程随笔【五】Thread线程创建及运行线程任务
- Java7并发编程--4.3、运行多个任务并处理结果
- JAVA 并发编程随笔【五】Thread线程创建及运行线程任务
- JAVA 并发编程随笔【五】Thread线程创建及运行线程任务
- JAVA 并发编程随笔【五】Thread线程创建及运行线程任务
- JAVA 并发编程随笔【五】Thread线程创建及运行线程任务
- Java并发编程高级篇(四):运行多个任务并处理第一个结果
- JAVA 并发编程随笔【五】Thread线程创建及运行线程任务
- JAVA 并发编程随笔【五】Thread线程创建及运行线程任务
- JAVA 并发编程随笔【五】Thread线程创建及运行线程任务
- Java并发编程-26-异步运行任务
- JAVA 并发编程随笔【五】Thread线程创建及运行线程任务
- JAVA 并发编程随笔【五】Thread线程创建及运行线程任务
- JAVA 并发编程随笔【五】Thread线程创建及运行线程任务
- 并发编程--运行多个任务并处理第一个结果
- JAVA 并发编程随笔【五】Thread线程创建及运行线程任务