什么是线程池
1、线程池就是一个可以复用线程的技术
2、不使用线程池,如果用户每发起一个请求,后台就创建一个新线程来处理,下次新任务来了有创建新线程,而创建新线程的开销很大,这样会严重影响系统性能
谁代表线程池以及如何获取线程池对象
1、JDk5提供了代表线程池的接口:ExecutorService
2、使用ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象
3、使用Executors(线程池工具类)调用方法返回不同特点的线程池对象
线程池的工作原理
1、首先线程池会有核心线程这种线程不会死亡,首先由核心线程对用户的请求进行处理
2、线程池会有任务队列,核心线程忙不过来处理的请求会先放到任务队列里
3、当线程池的核心线程忙不过来处理请求而且任务队列也满了时,会自动创建临时线程进行处理用户请求
4、可以指定临时线程,在没事干的情况下的存活时间
5、当线程池临时线程和核心线程都在忙时,且临时线程创建达到最大值 并且任务队列也满了时,新任务来时会开始拒绝任务
使用Executors(线程池工具类)的常用方法以及弊端
线程池如何处理Runnable以及Callable任务
1、处理Runnable任务,调用ExecutorServic的execute(Runnable r)方法
public class FileDemo {
public static void main(String[] args) {
//创建线程池对象
ExecutorService ex = new ThreadPoolExecutor(1,5,6,
TimeUnit.SECONDS, new ArrayBlockingQueue<>(5)
, Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
Runnable r = new MyThread(); //创建线程任务类对象
ex.execute(r);//启动线程池
}
}
class MyThread implements Runnable { //线程任务类
@Override
public void run() {
for (int i = 0; i < 6; i++) {
System.out.println(Thread.currentThread().getName() + "输出 Hello World" + i);
}
}
}
2、处理Callable任务时,调用ExecutorServic的ex.submit(Callable call)方法
public class FileDemo {
public static void main(String[] args) throws Exception {
//创建线程池对象
ExecutorService ex = new ThreadPoolExecutor(1,5,6,
TimeUnit.SECONDS, new ArrayBlockingQueue<>(5)
, Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
Callable<String> call = new MyThread();//创建线程任务类对象
Future<String> f = ex.submit(call); //获取返回结果
System.out.println(f.get());//
}
}
class MyThread implements Callable<String> { //线程任务类
@Override
public String call() throws Exception {
return "give me 100 yuan";
}
}