import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.rules.Stopwatch;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.util.StopWatch;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
*
*/
@Slf4j
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ExecutorTest.class)
public class ExecutorTest {
private Runnable mActive;
private ArrayDeque<Runnable> mArrayDeque = new ArrayDeque<>();
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
private static final int KEEP_ALIVE = 1;
private static final BlockingQueue sPoolWorkQueue = new LinkedBlockingDeque<>(128);
private static final ThreadFactory sThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "Serial thread #" + mCount.getAndIncrement());
}
};
private static final ThreadPoolExecutor THREAD_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE,
MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
/**
* 测试并行线程处理后再合并结果到主线程
* @throws InterruptedException
*/
@Test
public void Parallel() throws InterruptedException {
StopWatch sw = new StopWatch();
sw.start();
System.out.println("开始执行并行多线程任务... ...");
List<String> list = new ArrayList<String>();//任务返回结果
CountDownLatch countDownLatch = new CountDownLatch(10);//CountDownLatch是一个同步工具类,它通过一个计数器来实现的,初始值为线程的数量。每当一个线程完成了自己的任务,计数器的值就相应得减1。当计数器到达0时,表示所有的线程都已执行完毕,然后在等待的线程就可以恢复执行任务n
/**
* int corePoolSize 核心线程大小
* int maximumPoolSize 线程池最大容量大小
* long keepAliveTime 线程空闲时间,线程存活时间
* TimeUnit unit 时间单位
* BlockingQueue<Runnable> workQueue 任务队列 一个阻塞队列
*/
ExecutorService executorService = new ThreadPoolExecutor(10,10,0l, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());//创建线程池
for(int i=0;i<10;i++){
System.out.println("线程准备中... ...");
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
list.add(UUID.randomUUID().toString());
System.out.println("当前线程name:"+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
countDownLatch.countDown();
}
}
};
executorService.execute(runnable);
}
System.out.println("countDownLatch.getCount():"+countDownLatch.getCount());
countDownLatch.await();//主线程阻塞
System.out.println("下一步:countDownLatch.getCount():"+countDownLatch.getCount());
sw.stop();
System.out.println("submit总共cost时间:"+sw.getTotalTimeMillis());
executorService.shutdown();//等待线程执行完成,停止线程
System.out.println(list);//打印线程执行结果
}
/**
* 测试串行线程一个个的执行线程,执行结束后再执行主线程任务
*/
@Test
public void Serial() throws InterruptedException, ExecutionException {
StopWatch sw = new StopWatch();
sw.start();
System.out.println("开始执行串行多线程任务... ...");
List<String> list = new ArrayList<String>();//任务的返回结果
CountDownLatch countDownLatch = new CountDownLatch(10);
LinkedBlockingQueue<Runnable> tasks = new LinkedBlockingQueue<>();
//创建一个线程池
/**
* int corePoolSize 核心线程大小
* int maximumPoolSize 线程池最大容量大小
* long keepAliveTime 线程空闲时间,线程存活时间
* TimeUnit unit 时间单位
* BlockingQueue<Runnable> workQueue 任务队列 一个阻塞队列
*/
//方式二 先创建一个线程池 使用callable的阻塞方式实现多线程的串行执行
ExecutorService executorService = new ThreadPoolExecutor(10,10,0l,TimeUnit.MILLISECONDS,tasks);
// ExecutorService executorService = Executors.newSingleThreadExecutor();//方式一使用单线程方式实现线程串行执行
List<Callable<Integer>> lr = new ArrayList<Callable<Integer>>();
for(int i=0;i<10;i++){
System.out.println("线程准备中... ...");
int finalI = i;
Callable callable = new Callable<Integer>() {
public Integer call() throws Exception {
list.add(UUID.randomUUID().toString());
System.out.println(finalI+"当前线程name:"+Thread.currentThread().getName());
countDownLatch.countDown();
return finalI;
}
};
Future submit = executorService.submit(callable);
Object o = submit.get();
lr.add(callable);
}
// List<Future<Integer>> futures = executorService.invokeAll(lr);
//
// for(Future<Integer> f:futures){
// try {
// System.out.println(f.get());
// } catch (ExecutionException e) {
// e.printStackTrace();
// }
// }
// try {
// Thread.sleep(1500);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
System.out.println("countDownLatch.getCount():"+countDownLatch.getCount());
countDownLatch.await();//主线程阻塞
System.out.println("下一步:countDownLatch.getCount():"+countDownLatch.getCount());
sw.stop();
System.out.println("submit总共cost时间:"+sw.getTotalTimeMillis());
executorService.shutdown();//等待线程执行完成,停止线程
System.out.println(list);//打印线程执行结果
}
/**
* 测试串行线程一个个的执行线程,执行结束后再执行主线程任务
*/
@Test
public void Serial2() throws InterruptedException, ExecutionException {
StopWatch sw = new StopWatch();
sw.start();
System.out.println("开始执行串行多线程任务... ...");
List<String> list = new ArrayList<String>();//任务的返回结果
CountDownLatch countDownLatch = new CountDownLatch(10);
LinkedBlockingQueue<Runnable> tasks = new LinkedBlockingQueue<>();
//创建一个线程池
ExecutorService executorService = Executors.newSingleThreadExecutor();//方式一使用单线程方式实现线程串行执行
List<Callable<Integer>> lr = new ArrayList<Callable<Integer>>();
for(int i=0;i<10;i++){
System.out.println("线程准备中... ...");
int finalI = i;
Callable callable = new Callable<Integer>() {
public Integer call() throws Exception {
list.add(UUID.randomUUID().toString());
System.out.println(finalI+"当前线程name:"+Thread.currentThread().getName());
countDownLatch.countDown();
return finalI;
}
};
lr.add(callable);
}
List<Future<Integer>> futures = executorService.invokeAll(lr);
//
for(Future<Integer> f:futures){
try {
System.out.println(f.get());
} catch (ExecutionException e) {
e.printStackTrace();
}
}
// try {
// Thread.sleep(1500);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
System.out.println("countDownLatch.getCount():"+countDownLatch.getCount());
countDownLatch.await();//主线程阻塞
System.out.println("下一步:countDownLatch.getCount():"+countDownLatch.getCount());
sw.stop();
System.out.println("submit总共cost时间:"+sw.getTotalTimeMillis());
executorService.shutdown();//等待线程执行完成,停止线程
System.out.println(list);//打印线程执行结果
}
}
线程池实现多线程的并行执行和串行执行
最新推荐文章于 2024-08-15 10:46:07 发布