业务逻辑要求:每次调用多个任务,将任务分发给多个子线程,实现并行执行。本代码使用缓存线程池cacheThreadPool初始化多个线程,使用countdownlatch做子线程的计数控制,当子线程执行完,释放执行权,交给主线程,开始下一轮的执行。
话不多说:上代码
package com.test.thread;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by liujianfu on 2018/11/17.
*/
public class BatchTest {
private static int count=0;
//线程数
/**
* @param args
*/
public static void main(String[] args) {
while (true) {
if (count == 1) {
System.out.println("线程名字:" + Thread.currentThread().getName() + " 线程id:" + Thread.currentThread().getId() + "执行结束");
break;
}
//1.获取任务,设定10任务,待线程分配处理
final List<Integer> taskList = new ArrayList<Integer>();
for (int k = 0; k < 10; k++) {
System.out.println("线程名字:" + Thread.currentThread().getName() + " 线程id:" + Thread.currentThread().getId() + "查询集合");
taskList.add(k);
}
//线程数
int num = 5;
//CountDownLatch是一个同步辅助类也可以使用AtomicInteger替代
final CountDownLatch doneSignal = new CountDownLatch(num);
ExecutorService pool = Executors.newFixedThreadPool(num);
final BatchTest t =new BatchTest();
for (int k = 0; k < num; k++) {
//在未来某个时间执行给定的命令
System.out.println("线程名字:" + Thread.currentThread().getName() + " 线程id:" + Thread.currentThread().getId() + "开始执行");
final List<Integer> list = doWork(k, taskList);
System.out.println("线程名字:" + Thread.currentThread().getName() + " 线程id:" + Thread.currentThread().getId() + "获得任务集合");
pool.execute(new Runnable() {
public void run() {
//子线程的任务
try {
// System.out.println("线程:"+i+"休眠。。。。。");
System.out.println("线程名字:" + Thread.currentThread().getName() + " 线程id:" + Thread.currentThread().getId() + "休眠:");
Thread.sleep(1000);
t.consumer(list);
} catch (Exception e) {
e.printStackTrace();
}
//任务执行完毕递减锁存器的计数
System.out.println("线程名字:" + Thread.currentThread().getName() + " 线程id:" + Thread.currentThread().getId() + "count前");
doneSignal.countDown();
System.out.println("线程名字:" + Thread.currentThread().getName() + " 线程id:" + Thread.currentThread().getId() + "count后");
}
});
}
try {
System.out.println("await前");
doneSignal.await();
System.out.println("await后");
} catch (Exception e) {
e.printStackTrace();
}
//子线程执行完毕,可以开始后续任务处理了
System.out.println("所有任务执行完毕");
count++;
System.out.println("========");
}
}
public static List<Integer> doWork(int i,List<Integer> taskList) {
int totalSize = taskList.size();
int ts = 5;
if (ts > totalSize) {
ts = totalSize;
}
int m = totalSize / ts;
int startIndex = i * m;
int endIndex = (i + 1) * m;
if (i == ts - 1) {
endIndex = totalSize;
}
List<Integer> tempIds = taskList.subList(startIndex, endIndex);
return tempIds;
}
public void consumer(List<Integer> tempIds){
for(int k=0;k<tempIds.size();k++){
System.out.println("线程名字:"+Thread.currentThread().getName()+" 线程id:"+Thread.currentThread().getId()+"消费任务:"+tempIds.get(k));
}
System.out.println("线程名字:"+Thread.currentThread().getName()+" 线程id:"+Thread.currentThread().getId()+"本线程消费结束");
}
}
执行结果:
线程名字:main 线程id:1查询集合
线程名字:main 线程id:1查询集合
线程名字:main 线程id:1查询集合
线程名字:main 线程id:1查询集合
线程名字:main 线程id:1查询集合
线程名字:main 线程id:1查询集合
线程名字:main 线程id:1查询集合
线程名字:main 线程id:1查询集合
线程名字:main 线程id:1查询集合
线程名字:main 线程id:1查询集合
线程名字:main 线程id:1开始执行
线程名字:main 线程id:1获得任务集合
线程名字:main 线程id:1开始执行
线程名字:main 线程id:1获得任务集合
线程名字:main 线程id:1开始执行
线程名字:main 线程id:1获得任务集合
线程名字:pool-1-thread-1 线程id:11休眠:
线程名字:main 线程id:1开始执行
线程名字:main 线程id:1获得任务集合
线程名字:pool-1-thread-3 线程id:13休眠:
线程名字:main 线程id:1开始执行
线程名字:main 线程id:1获得任务集合
await前
线程名字:pool-1-thread-5 线程id:15休眠:
线程名字:pool-1-thread-2 线程id:12休眠:
线程名字:pool-1-thread-4 线程id:14休眠:
线程名字:pool-1-thread-1 线程id:11消费任务:0
线程名字:pool-1-thread-1 线程id:11消费任务:1
线程名字:pool-1-thread-1 线程id:11本线程消费结束
线程名字:pool-1-thread-1 线程id:11count前
线程名字:pool-1-thread-1 线程id:11count后
线程名字:pool-1-thread-3 线程id:13消费任务:4
线程名字:pool-1-thread-3 线程id:13消费任务:5
线程名字:pool-1-thread-3 线程id:13本线程消费结束
线程名字:pool-1-thread-3 线程id:13count前
线程名字:pool-1-thread-3 线程id:13count后
线程名字:pool-1-thread-2 线程id:12消费任务:2
线程名字:pool-1-thread-2 线程id:12消费任务:3
线程名字:pool-1-thread-2 线程id:12本线程消费结束
线程名字:pool-1-thread-2 线程id:12count前
线程名字:pool-1-thread-2 线程id:12count后
线程名字:pool-1-thread-5 线程id:15消费任务:8
线程名字:pool-1-thread-5 线程id:15消费任务:9
线程名字:pool-1-thread-5 线程id:15本线程消费结束
线程名字:pool-1-thread-5 线程id:15count前
线程名字:pool-1-thread-5 线程id:15count后
线程名字:pool-1-thread-4 线程id:14消费任务:6
线程名字:pool-1-thread-4 线程id:14消费任务:7
线程名字:pool-1-thread-4 线程id:14本线程消费结束
线程名字:pool-1-thread-4 线程id:14count前
线程名字:pool-1-thread-4 线程id:14count后
await后
所有任务执行完毕
========
线程名字:main 线程id:1执行结束
可以看到:10个任务,分配给5个线程,每个线程分别获取2个线程,获取的线程彼此不相交。