例子:我们有一个集合0~100000,现需要计算其中的偶数。
1.首先我们用寻常的方法:
(1)通过循环来解决:
@Test
public void test1(){
final int size = 10000000; // 处理的集合大小
// final int nThreads = 4; // 线程数
List<String> list = new ArrayList<String>(size);
for (int i = 0; i < size; i++)
{
list.add(i + "");
}
List<String> list1 = new ArrayList<String>();
for (int i = 0; i < list.size(); i++) {
if (Integer.parseInt(list.get(i)) % 2 == 0){
list1.add(list.get(i));
}
}
System.out.println(list1);
}
2.下面我们用线程池创建多线程的方法操作:
(1)写出子线程的方法:
public class CallableDemo implements Callable<List<String>> {
private List<String> list;
//构造函数,用于传送数据进来
public CallableDemo(List<String> list) {
this.list = list;
}
public List<String> call() throws Exception {
// 标记子线程开始
System.out.println(Thread.currentThread().getName() + " Callable 子线程开始...");
//结果存储
List<String> resultList = new ArrayList<String>();
// 业务逻辑处理
for (String single : list) {
if (Integer.parseInt(single) % 2 == 0) {
resultList.add(single);
}
}
// 标记子线程结束
System.out.println(Thread.currentThread().getName() + " Callable 子线程结束...");
return resultList;
}
}
(2)写出主线程的方法:
public class DealListDemo {
/**
* @param list 待处理集合
* @param nThreads 线程数量
* @return
*/
public List<String> dealListMulti(List<String> list, int nThreads) {
if (list == null || list.size() < 1) {
throw new NullPointerException("the collection is null");
}
//计算每个分组存多个数据
int capactiy = list.size() % nThreads > 0 ? list.size() / nThreads : list.size() / nThreads + 1;
//进行数据分组(分任务)例如,对包含[a,b,c,d,e]的列表进行分区,分区大小为3,得到[[a,b,c],[d,e]]——一个包含三个和两个元素的两个内部列表的外部列表,所有列表都按原始顺序排列。
List<List<String>> partions = Lists.partition(list, capactiy);
// 创建一个临时的局部线程池(固定大小)
ExecutorService executorService = Executors.newFixedThreadPool(nThreads);
// 保存结果
List<Future<List<String>>> futures = new ArrayList<Future<List<String>>>(partions.size());
// 分配任务
for (int i = 0; i < partions.size(); i++) {
// 小任务
CallableDemo callTask = new CallableDemo(partions.get(i));
//同步执行多个小任务
futures.add(executorService.submit(callTask));
}
// 关闭线程池
executorService.shutdown();
// 合并
List<String> result = new ArrayList<String>();
for (Future<List<String>> future : futures) {
try {
// 合并
result.addAll(future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
System.out.println("主线程结束");
return result;
}
}
(3)进行测试:
@Test
public void test()
{
final int size = 10000000; // 处理的集合大小
final int nThreads = 1000; // 线程数
List<String> list = new ArrayList<String>(size);
for (int i = 0; i < size; i++)
{
list.add(i + "");
}
List<String> list2 = new DealListDemo().dealListMulti(list, nThreads);
System.out.println(list2);
}