可以用于excel导出场景
直接上代码:
package com.threadmore;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class MutiThreadQuery {
public List<Object> queryMethedOne() {
ThreadPoolExecutor executor =
new ThreadPoolExecutor(5, 10, 1, TimeUnit.MINUTES,
new ArrayBlockingQueue<Runnable>(10),
new ThreadPoolExecutor.CallerRunsPolicy());
System.out.println("start thread pool...");
List<Object> resultList = new ArrayList<Object>();
//查询页数(批次)
int pageIndex = 0;
int n = 30;//当页数小于n(总线程数)时,跳出
do {
MergeRunnable mr = new MergeRunnable(resultList, pageIndex);
executor.execute(mr);
System.out.println("pageIndex:"+pageIndex);
pageIndex++;
}while(pageIndex < n);//当页数小于n(总线程数)时,跳出
executor.shutdown();//不能再提交新任务
boolean loop = true;
try {
do {//等待所有任务完成
System.out.println("线程池中线程数目:" + executor.getPoolSize());
System.out.println("队列中等待执行的任务数目:" + executor.getQueue().size());
System.out.println("已执行完的任务数目:" + executor.getCompletedTaskCount());
System.out.println("当前的resultList数量:" + resultList.size());
System.out.println("总共记录数:" + "xxx");
//阻塞,直到线程池所有的任务结束,2秒判断一次
loop = !executor.awaitTermination(2, TimeUnit.SECONDS);
}while(loop);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return resultList;
}
class MergeRunnable implements Runnable{
private List<Object> allRest;
private int pageIndex;
public MergeRunnable(List<Object> resultList, int pageIndex) {
this.allRest = resultList;
this.pageIndex = pageIndex;
}
@Override
public void run() {
System.err.println(Thread.currentThread().getName() +" query data start...");
List<Object> tempPageRest = queryFromDataBase(pageIndex);
synchronized(allRest) {
allRest.addAll(tempPageRest);
}
System.err.println(Thread.currentThread().getName() +" query data end...");
}
}
private List<Object> queryFromDataBase(int pageIndex) {
// TODO do some operation from database
try {
Thread.sleep(10*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
List<Object> test = new ArrayList<Object>();
return test;
}
//----------------------------华丽的分割线----以下是第二种写法,为了测试和第一种有没有性能上的差别---------
public List<Object> queryMethedTwo() {
ThreadPoolExecutor executor =
new ThreadPoolExecutor(5, 10, 1, TimeUnit.MINUTES,
new ArrayBlockingQueue<Runnable>(10),
new ThreadPoolExecutor.CallerRunsPolicy());
System.out.println("start thread pool...");
List<Object> resultList = new ArrayList<Object>();
//查询页数(批次)
int pageIndex = 0;
int n = 30;//当页数小于n(总线程数)时,跳出
CountDownLatch latch = new CountDownLatch(n);
for (int i = 0; i < n; i++) {
MergeRunnable1 mr1 = new MergeRunnable1(resultList, pageIndex, latch);
executor.execute(mr1);
System.out.println("pageIndex:"+pageIndex);
pageIndex++;
}
executor.shutdown();
try {
latch.await(2,TimeUnit.MINUTES);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return resultList;
}
class MergeRunnable1 implements Runnable{
private List<Object> allRest;
private int pageIndex;
private CountDownLatch latch;
public MergeRunnable1(List<Object> resultList, int pageIndex, CountDownLatch latch) {
this.allRest = resultList;
this.pageIndex = pageIndex;
this.latch = latch;
}
@Override
public void run() {
System.err.println(Thread.currentThread().getName() +" query data start...");
List<Object> tempPageRest = queryFromDataBase(pageIndex);
synchronized(allRest) {
allRest.addAll(tempPageRest);
}
latch.countDown();
System.err.println(Thread.currentThread().getName() +" query data end...");
}
}
//----------------------------华丽的分割线----以下是第二种写法,为了测试和第一种有没有性能上的差别---------
public static void main(String[] args) {
MutiThreadQuery m = new MutiThreadQuery();
long a = System.currentTimeMillis();
m.queryMethedOne();
// m.queryMethedTwo();
System.out.println("#################:"+(System.currentTimeMillis() - a)+"ms");
}
}
之后一篇主要分析多线程包中API使用细节。