package com.yongyou.test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;
import com.sande.user.utils.ThreadPool;
class PrintTask3 extends RecursiveAction {
// 个“小任务”最多只打印50个数
private static final int THRESHOLD = 50;
private int start;
private int end;
// 打印从 start 到 end 的任务
private List<String> list;
public PrintTask3(int start,int end,List<String> list) {
this.start = start;
this.end = end;
this.list = list;
}
//@SuppressWarnings("hiding")
@Override
protected void compute() {
//Integer rest = 100;
List<String> listString = new ArrayList<>();
// 当 end 与 start 之间的差小于 THRESHOLD 时,开始打印
if (end - start < THRESHOLD) {
// 业务逻辑写在这个 for 循环中
for (int i = start; i<end; i++) {
listString.add(list.get(i));
System.out.println(Thread.currentThread().getName()
+ "的 i 值:" + i);
try {
// 1000个任务,每批50个线程执行,总共需要分成20批,每批都会暂停5毫秒。
// 执行完一批再执行下一批。每一批都是50个线程同时执行,如果每个操作执行要
// 2秒,50个线程同时执行只有大概2秒可以执行完50操作,如果不用线程池串行执行,完成这50个操作就需要
// 需要100秒。
Thread.sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} else {
// 当 end 与 start 之间的差大于 THRESHOLD,即要打印数超过 50 个时
// 将大任务分解成两个“小任务”
int middle = (start + end) / 2;
PrintTask3 left = new PrintTask3(start, middle,list);
PrintTask3 right = new PrintTask3(middle, end,list);
// 并行执行两个 "小任务"
left.fork();
right.fork();
}
for (String string : listString) {
System.out.println("计算结果:" + string);
}
}
}
public class ForkJoinPoolTest3 {
public static void main(String[] args) throws Exception {
Future<List<String>> restValue;
ForkJoinPool pool = new ForkJoinPool();
List<String> list2 = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
list2.add("test"+i);
}
// 提交可分解的 PrintTask 任务
pool.submit(new PrintTask3(0, 1000,list2));
//线程阻塞100秒,等待所有任务完成。如果100秒还有任务没执行完成,线程池会关闭,退出任务,
//就会导致部分任务没完成
pool.awaitTermination(100, TimeUnit.SECONDS);
System.out.println("输出完成");
// 关闭线程池
pool.shutdown();
}
}
package com.yongyou.test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;
import com.sande.user.utils.ThreadPool;
class PrintTask2 extends RecursiveTask<List<String>> {
// 个“小任务”最多只打印50个数
private static final int THRESHOLD = 50;
private int start;
private int end;
// 打印从 start 到 end 的任务
private List<String> list;
public PrintTask2(int start,int end,List<String> list) {
this.start = start;
this.end = end;
this.list = list;
}
//@SuppressWarnings("hiding")
@Override
protected List<String> compute() {
//Integer rest = 100;
List<String> listString = new ArrayList<>();
// 当 end 与 start 之间的差小于 THRESHOLD 时,开始打印
if (end - start < THRESHOLD) {
// 业务逻辑写在这个 for 循环中
for (int i = start; i<end; i++) {
listString.add(list.get(i));
System.out.println(Thread.currentThread().getName()
+ "的 i 值:" + i);
}
return listString;
} else {
// 当 end 与 start 之间的差大于 THRESHOLD,即要打印数超过 50 个时
// 将大任务分解成两个“小任务”
int middle = (start + end) / 2;
PrintTask2 left = new PrintTask2(start, middle,list);
PrintTask2 right = new PrintTask2(middle, end,list);
// 并行执行两个 "小任务"
left.fork();
right.fork();
left.join().addAll(right.join());
return left.join();
}
//return rest;
//return listString;
}
/*@Override
protected V compute() {
// TODO Auto-generated method stub
return null;
}*/
}
public class ForkJoinPool2Test {
public static void main(String[] args) throws Exception {
Future<List<String>> restValue;
ForkJoinPool pool = new ForkJoinPool(2);
List<String> list2 = new ArrayList<>();
//List<String> list3 = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
list2.add("test"+i);
}
// 提交可分解的 PrintTask 任务
restValue = pool.submit(new PrintTask2(0, 1000,list2));
pool.awaitTermination(2, TimeUnit.SECONDS);
for (String string : restValue.get()) {
System.out.println("计算结果");
System.out.println(string);
}
System.out.println("输出完成");
// 关闭线程池
pool.shutdown();
}
}