今天又是周末,公司同样开了空调,因此趁这个机会记录下ForkJoin框架的使用记录
public class ComputeTask extends RecursiveTask<Integer> {
private static final int THRESHOLD = 100 * 1000;
private List<String> list;
private int start;
private int end;
public ComputeTask(List<String> list, int start, int end) {
this.list = list;
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
int count = 0;
if ((end - start) <= THRESHOLD) {
for (int i = start; i <= end; i++) {
if (("A").equals(list.get(i))) {
Mock.mockReal();
count = count + 1;
}
}
} else {
int middle = (start + end) / 2;
ComputeTask leftTask = new ComputeTask(list, start, middle);
ComputeTask rightTask = new ComputeTask(list, middle + 1, end);
leftTask.fork();
rightTask.fork();
count = leftTask.join() + rightTask.join();
}
return count;
}
}
public class MainClient {
private static List<String> letters = new ArrayList<>(1000 * 1000);
public static void initData() {
// fill the big array with A-Z randomly
for (int i = 0; i < 1000 * 1000; i++) {
char t = (char) (Math.random() * 26 + 65);
letters.add(String.valueOf(t)); // A-Z
}
}
public static void main(String args[]) throws Exception {
MainClient mainClient = (MainClient) TimeAnalysisProxy.build().getInstance(new MainClient());
initData();
mainClient.forkJoinCount(letters);
mainClient.taskCount(letters);
}
public int forkJoinCount(List<String> letters) throws Exception {
ForkJoinPool forkJoinPool = new ForkJoinPool();
try {
ComputeTask computeTask = new ComputeTask(letters, 1, letters.size() - 1);
Future future = forkJoinPool.submit(computeTask);
return Integer.parseInt(String.valueOf(future.get()));
} finally {
forkJoinPool.shutdown();
}
}
public int taskCount(final List<String> letters) throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(1);
try {
Future<Integer> future = executorService.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int count = 0;
for (int i = 0; i < letters.size(); i++) {
if ("A".equals(letters.get(i))) {
Mock.mockReal();
count++;
}
}
return count;
}
});
return future.get();
} finally {
executorService.shutdown();
}
}
}
public class TimeAnalysisProxy implements MethodInterceptor {
private Object target;
public static TimeAnalysisProxy build() {
return new TimeAnalysisProxy();
}
public Object getInstance(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
long startTime = System.currentTimeMillis();
Object object = methodProxy.invokeSuper(o, objects);
long endTime = System.currentTimeMillis();
System.out.println(
method.getName() + " result:" + String.valueOf(object) + " costTime: " + (endTime - startTime) +
"ms");
return object;
}
}
public class Mock {
private static Random random = new Random();
public static void mockReal() {
try {
Thread.currentThread().sleep(random.nextInt(2));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
forkJoinCount result:38781 costTime: 8689ms
taskCount result:38781 costTime: 19483ms