1、创建单个线程池
只有一个线程执行 用的很少
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.submit(() -> {
System.out.println("线程:" + Thread.currentThread().getName());
});
2、缓存线程池
随着任务的提交可以无限去创建下去 可能导致cpu飙升
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 100; i++) {
executorService.submit(() -> {
System.out.println("线程:" + Thread.currentThread().getName());
});
}
3、定长线程池
固定线程池的大小 如果线程池太小 线程数少了 任务执行的慢 会放入队列 可能出现内存溢出
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i = 0; i < 100; i++) {
executorService.submit(() -> {
System.out.println("线程:" + Thread.currentThread().getName());
});
}
4、定时线程池
多长时间后执行 我这里写的是5秒
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
scheduledExecutorService.schedule(()->{
System.out.println("线程:" + Thread.currentThread().getName());
},5, TimeUnit.SECONDS);
5
当创建一个线程池的时候,一个线程都没有,随着任务的提交,会拿到当前线程数和核心线程数比较如果小于,继续创建线程、如果超过了核心线程数,会把当前任务放到阻塞队列,
如果队列没有满继续放,如果队列满了,会拿到当前线程数和最大线程数做笔记,如果小于
继续创建线程,超过出发拒绝策略
/*
ThreadPoolExecutor(int corePoolSize 核心线程数,
int maximumPoolSize 最大线程数,
long keepAliveTime 线程存活时间,
TimeUnit unit,
BlockingQueue<Runnable> workQueue 阻塞队列)*/
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 3, 2, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(2)
);
//当前线程数:0,核心线程数:2
//创建线程 执行代码
threadPoolExecutor.submit(()->{
System.out.println("线程1:" + Thread.currentThread().getName());
//线程5的 时候加休眠
try {
Thread.sleep(2000L);
} catch (Exception e) {
e.printStackTrace();
}
});
//当前线程数:1,核心线程数:2
//当前线程数:1,核心线程数:2 1<2 继续创建线程
threadPoolExecutor.submit(()->{
System.out.println("线程2:" + Thread.currentThread().getName());
//线程5的 时候加休眠
try {
Thread.sleep(2000L);
} catch (Exception e) {
e.printStackTrace();
}
});
//当前线程数:2,核心线程数:2 阻塞队列:0
//当前线程数:2,核心线程数:2 2!<2 所以会把下面这个线程放到阻塞队列内 线程1和线程2谁先执行完毕再来处理线程3
threadPoolExecutor.submit(()->{
System.out.println("线程3:" + Thread.currentThread().getName());
//线程5的 时候加休眠
try {
Thread.sleep(2000L);
} catch (Exception e) {
e.printStackTrace();
}
});
//当前线程数:2,核心线程数:2 阻塞队列:1
// 阻塞队列为2 上一步阻塞队列内为1 所以与上一步同理
threadPoolExecutor.submit(()->{
System.out.println("线程4:" + Thread.currentThread().getName());
//线程5的 时候加休眠
try {
Thread.sleep(2000L);
} catch (Exception e) {
e.printStackTrace();
}
});
//把最大线程数改为4
//当前线程数:2,核心线程数:2 阻塞队列:2 最大线程数:4 2<4
threadPoolExecutor.submit(()->{
System.out.println("线程5:" + Thread.currentThread().getName());
try {
Thread.sleep(2000L);
} catch (Exception e) {
e.printStackTrace();
}
});
//当前线程数:3,核心线程数:2 阻塞队列:2 最大线程数:4 3<4
threadPoolExecutor.submit(()->{
System.out.println("线程6:" + Thread.currentThread().getName());
try {
Thread.sleep(2000L);
} catch (Exception e) {
e.printStackTrace();
}
});
//当前线程数:4,核心线程数:2 阻塞队列:2 最大线程数:4 4!<4
// 触发拒绝策略
threadPoolExecutor.submit(()->{
System.out.println("线程7:" + Thread.currentThread().getName());
try {
Thread.sleep(2000L);
} catch (Exception e) {
e.printStackTrace();
}
});
6 、其他的一些方法
//运行一个异步线程 无返回值
// CompletableFuture.runAsync(()->{
// System.out.println("线程" + Thread.currentThread().getName());
// });
//运行一个异步线程 有返回值
CompletableFuture<String> f1 = CompletableFuture.supplyAsync(() -> {
System.out.println("线程2" + Thread.currentThread().getName());
return "线程2";
});
try {
//获取返回结果
String str = f1.get();
System.out.println("返回结果:"+str);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
//f1 执行完成后 继续开启线程执行
f1.thenApplyAsync((str)->{
System.out.println("线程3" + Thread.currentThread().getName()+" "+str);
return "线程3";
});
//用于判断其他线程执行完后在干其他事情
CountDownLatch countDownLatch = new CountDownLatch(5);
// 等待所有线程执行完成后 主线程在继续执行
CompletableFuture.allOf();
// 等待所有线程执行完成后 主线程在继续执行 为0才继续执行
countDownLatch.await();
//线程池大小设置
int cpuCore = Runtime.getRuntime().availableProcessors();
System.out.println(cpuCore);
//CPU密集度(1 或者2*cpu核数) IO密集的(3 或者4*cpu核数)
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 4, 2, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(2));
CompletableFuture.runAsync(() -> {
System.out.println("线程" + Thread.currentThread().getName());
},threadPoolExecutor);
try {
Thread.sleep(2000L);
} catch (Exception e) {
e.printStackTrace();
}