什么是线程池?
线程池就是一个可以复用线程的技术。
不使用线程池的问题:
如果用户每发起一个请求,后台就创建一个新线程来处理,下次新任务来了又要创建新线程,而创建新线程的开销是很大的,这样会严重影响系统的性能。
文章图片
线程池常见面试题:
1、临时线程什么时候创建?
【JAVA|线程池处理任务】新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以创建临时线程,此时才会创建临时线程。
2、什么时候会开始拒绝任务?
核心线程和临时线程都在忙,任务队列也满了,新的任务过来的时候才会开始任务拒绝。
1、线程池处理Runnable任务
import java.util.concurrent.*;
public class 多线程_5线程池处理Runnable任务 {
public static void main(String[] args) {
//线程池处理Runnable任务
//创建线程池对象
/*
public ThreadPoolExecutor(int corePoolSize,//核心线程数量
int maximumPoolSize,//线程池可支持的最大线程数量
long keepAliveTime,//临时线程的最大存活时间
TimeUnit unit,//指定存活时间的单位(秒,分等)
BlockingQueue workQueue,//指定任务队列
ThreadFactory threadFactory,//指定用哪个线程工厂创建线程
RejectedExecutionHandler handler)//指定线程忙,任务满了的时候,新任务来了怎么办
*/
ExecutorService pool=new ThreadPoolExecutor(3,5,
6, TimeUnit.SECONDS,new ArrayBlockingQueue<>(5),
Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
//给任务线程池处理
Runnable r=new MyExe();
//三个核心线程
pool.execute(r);
pool.execute(r);
pool.execute(r);
//五个任务队列(不创建临时线程时,会发现只有三个线程,即核心线程量)
pool.execute(r);
pool.execute(r);
pool.execute(r);
pool.execute(r);
pool.execute(r);
//创建临时线程(五个线程,即最大线程量)
pool.execute(r);
pool.execute(r);
//不创建,拒绝策略被触发
// pool.execute(r);
//关闭线程池(开发中一般不会使用)
//pool.shutdownNow();
//立即关闭,即使任务没有执行完毕。会丢失任务的!
//pool.shutdown();
//会等待任务全部执行完毕后再关闭(建议使用)}
}
class MyExe implements Runnable{
public void run(){
for (int i = 1;
i <=6 ;
i++) {
System.out.println(Thread.currentThread().getName()+"正在执行:"+i+"次");
}
//因为当前案例任务太简单,我们需要创建临时队列需要让三个核心线程忙,五个任务队列排满,所以让线程休眠以增加任务时间
try {
System.out.println(Thread.currentThread().getName()+"任务与线程绑定,线程进入了休眠");
Thread.sleep(1000000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
文章图片
文章图片
2、线程池处理Callable任务
import java.util.concurrent.*;
public class 多线程_5线程池处理Callable任务 {
public static void main(String[] args) throws Exception {
//线程池处理Callable任务
//创建线程池对象
/*
public ThreadPoolExecutor(int corePoolSize,//核心线程数量
int maximumPoolSize,//线程池可支持的最大线程数量
long keepAliveTime,//临时线程的最大存活时间
TimeUnit unit,//指定存活时间的单位(秒,分等)
BlockingQueue workQueue,//指定任务队列
ThreadFactory threadFactory,//指定用哪个线程工厂创建线程
RejectedExecutionHandler handler)//指定线程忙,任务满了的时候,新任务来了怎么办
*/
ExecutorService pool=new ThreadPoolExecutor(3,5,
6, TimeUnit.SECONDS,new ArrayBlockingQueue<>(5),
Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
//给任务线程池处理
//Callable c=new MyCallable2(100);
//pool.submit(c);
Future f1=pool.submit(new MyCallable2(100));
Future f2=pool.submit(new MyCallable2(200));
Future f3=pool.submit(new MyCallable2(300));
Future f4=pool.submit(new MyCallable2(400));
Future f5=pool.submit(new MyCallable2(500));
//String str=f1.get();
//System.out.println(str);
System.out.println(f1.get());
System.out.println(f2.get());
System.out.println(f3.get());
System.out.println(f4.get());
System.out.println(f5.get());
}
}
class MyCallable2 implements Callable {
//v(泛型)
private int n;
public MyCallable2(int n) {
this.n = n;
}
//重写call方法
//案例:加法
public String call() throws Exception {
int sum = 0;
for (int i = 1;
i <=n;
i++) {
sum += i;
}
return Thread.currentThread().getName()+"执行 1-"+n+"的和,结果为:" + sum;
}
}
文章图片
推荐阅读
- JAVA|多线程之定时器&&一些面试题
- JAVA|第一届AcWing Cup决赛两个闹钟问题
- JAVA|斗地主游戏基础版
- JAVA|特殊的四位十进制
- java基础|Java 多线程(超详细)
- Java基础|Java读写Properties配置文件(Properties类)
- Java基础|Java这些IO流你了解嘛
- Java基础|抽象类/接口/内部类
- Java基础|浅学一下I/O流和File类文件操作