如何显示在Java Fork/Join框架中发生的工作窃取?
我想改进一下我的fork/join小示例,以说明在Java fork/join框架执行过程中会发生工作窃取 我需要对以下代码做哪些更改?示例目的:只需对一个值进行线性研究,将多个线程之间的工作分解如何显示在Java Fork/Join框架中发生的工作窃取?,java,fork-join,work-stealing,Java,Fork Join,Work Stealing,我想改进一下我的fork/join小示例,以说明在Java fork/join框架执行过程中会发生工作窃取 我需要对以下代码做哪些更改?示例目的:只需对一个值进行线性研究,将多个线程之间的工作分解 package com.stackoverflow.questions; import java.util.LinkedList; import java.util.List; import java.util.Random; import java.util.concurrent.ForkJoin
package com.stackoverflow.questions;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
public class CounterFJ<T extends Comparable<T>> extends RecursiveTask<Integer> {
private static final long serialVersionUID = 5075739389907066763L;
private List<T> _list;
private T _test;
private int _lastCount = -1;
private int _start;
private int _end;
private int _divideFactor = 4;
private static final int THRESHOLD = 20;
public CounterFJ(List<T> list, T test, int start, int end, int factor) {
_list = list;
_test = test;
_start = start;
_end = end;
_divideFactor = factor;
}
public CounterFJ(List<T> list, T test, int factor) {
this(list, test, 0, list.size(), factor);
}
@Override
protected Integer compute() {
if (_end - _start < THRESHOLD) {
int count = 0;
for (int i = _start; i < _end; i++) {
if (_list.get(i).compareTo(_test) == 0) {
count++;
}
}
_lastCount = count;
return new Integer(count);
}
LinkedList<CounterFJ<T>> taskList = new LinkedList<>();
int step = (_end - _start) / _divideFactor;
for (int j = 0; j < _divideFactor; j++) {
CounterFJ<T> task = null;
if (j == 0)
task = new CounterFJ<T>(_list, _test, _start, _start + step, _divideFactor);
else if (j == _divideFactor - 1)
task = new CounterFJ<T>(_list, _test, _start + (step * j), _end, _divideFactor);
else
task = new CounterFJ<T>(_list, _test, _start + (step * j), _start + (step * (j + 1)), _divideFactor);
// task.fork();
taskList.add(task);
}
invokeAll(taskList);
_lastCount = 0;
for (CounterFJ<T> task : taskList) {
_lastCount += task.join();
}
return new Integer(_lastCount);
}
public int getResult() {
return _lastCount;
}
public static void main(String[] args) {
LinkedList<Long> list = new LinkedList<Long>();
long range = 200;
Random r = new Random(42);
for (int i = 0; i < 1000; i++) {
list.add(new Long((long) (r.nextDouble() * range)));
}
CounterFJ<Long> counter = new CounterFJ<>(list, new Long(100), 4);
ForkJoinPool pool = new ForkJoinPool();
long time = System.currentTimeMillis();
pool.invoke(counter);
System.out.println("Fork join counter in " + (System.currentTimeMillis() - time));
System.out.println("Occurrences:" + counter.getResult());
}
}
package com.stackoverflow.questions;
导入java.util.LinkedList;
导入java.util.List;
导入java.util.Random;
导入java.util.concurrent.ForkJoinPool;
导入java.util.concurrent.RecursiveTask;
公共类扩展递归任务{
私有静态最终长serialVersionUID=5075739389907066763L;
私人名单(private List);;
私人T_检验;
私有整数_lastCount=-1;
私人互联网启动;
私人互联网终端;
私有整数除以因子=4;
私有静态最终整数阈值=20;
公共计数器j(列表、T检验、整数开始、整数结束、整数因子){
_列表=列表;
_测试=测试;
_开始=开始;
_结束=结束;
_分割因子=因子;
}
公共系数j(列表、T检验、整数因子){
这(list,test,0,list.size(),factor);
}
@凌驾
受保护整数计算(){
如果(\u结束-\u开始<阈值){
整数计数=0;
for(int i=\u start;i<\u end;i++){
如果(_list.get(i).compareTo(_test)==0){
计数++;
}
}
_lastCount=计数;
返回新的整数(计数);
}
LinkedList taskList=新建LinkedList();
int step=(\u end-\u start)/\u分割因子;
对于(int j=0;j<_divideFactor;j++){
任务=null;
如果(j==0)
任务=新的计数器(_列表、_测试、_开始、_开始+步骤、_分割因子);
else if(j==\u分割因子-1)
任务=新的计数器j(_列表、_测试、_开始+(步骤*j)、_结束、_分割因子);
其他的
任务=新的计数器j(_列表,_测试,_开始+(步骤*j),_开始+(步骤*(j+1)),_分割因子);
//task.fork();
任务列表。添加(任务);
}
invokeAll(任务列表);
_lastCount=0;
用于(任务:任务列表){
_lastCount+=任务。加入();
}
返回新整数(_lastCount);
}
public int getResult(){
返回上次计数;
}
公共静态void main(字符串[]args){
LinkedList=新建LinkedList();
远程=200;
随机r=新随机(42);
对于(int i=0;i<1000;i++){
添加(新长((长)(r.nextDouble()*范围));
}
计数器=新计数器(列表,新长(100),4);
ForkJoinPool池=新的ForkJoinPool();
长时间=System.currentTimeMillis();
调用(计数器);
System.out.println(“Fork join counter in”+(System.currentTimeMillis()-time));
System.out.println(“出现次数:+counter.getResult());
}
}
我终于学会了如何去做,这并不难,所以我把这个留给未来的读者
在创建实例本身的RecursiveTask
save线程的costructor中。在compute
方法中,检查执行线程是否相同。如果没有,工作盗窃已经发生
所以我添加了这个成员变量
private long _threadId = -1;
private static int stolen_tasks = 0;
更改的构造函数如下所示:
public CounterFJ(List<T> list, T test, int start, int end, int factor) {
_list = list;
_threadId = Thread.currentThread().getId(); //added
_test = test;
_start = start;
_end = end;
_branchFactor = factor;
}
+谢谢你为解决自己的问题所做的努力。非常感谢,@Trying
@Override
protected Integer compute() {
long thisThreadId = Thread.currentThread().getId();
if (_threadId != thisThreadId){
stolen_tasks++;
}
// rest of the method