目录
- 线程池
- 什么是线程池?
- 为什么用线程池?
- 线程池原理
- 常见四种线程池和自定义线程池
线程池
什么是线程池?
池化技术
为什么用线程池?
1 由于设置最大线程数,防止线程过多而导致系统崩溃。
2 线程复用,不需要频繁创建或销毁线程,并且销毁和创建是耗费时间和资源操作,所以提高了效率,节约资源。
线程池原理
核心线程,等待队列,非核心线程,拒绝策略
如果有空闲的线程直接使用,没有空闲的线程并且线程数量未达到corePoolSize,则新建一个线程(核心线程)执行任务
线程数量达到了corePoolSize,则将任务移入队列等待空闲线程将其取出去执行(通过getTask() 方法从阻塞队列中获取等待的任务,如果队列中没有任务,getTask()方法会被阻塞并挂起,不会占用cpu资源,整个getTask操作在自旋下完成)
队列已满,新建线程(非核心线程)执行任务,空闲下来以后,非核心线程会按照时间策略进行销毁
队列已满,总线程数又达到了maximumPoolSize,就会执行任务拒绝策略。
handler:表示当拒绝处理任务时的策略(①AbortPolicy丢弃任务并抛出RejectedExecution异常;②DiscardPolicy丢弃任务,但是不抛出异常;③DiscardOldestPolicy丢弃队列最前面的任务,然后重新尝试执行任务;④CallerRunsPolicy由调用线程处理该任务)
常见四种线程池和自定义线程池
见文档
代码
PoolTest1
public class PoolTest1 {public static void main(String[] args) {
// ExecutorService executorService1 = Executors.newCachedThreadPool();
// ExecutorService executorService2 = Executors.newFixedThreadPool(5);
// ExecutorService executorService3 = Executors.newSingleThreadExecutor();
// ScheduledExecutorService executorService4 = Executors.newScheduledThreadPool(5);ThreadPoolExecutor executorService = new ThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10), new ThreadPoolExecutor.AbortPolicy());// 执行任务-线程不用我们创建,交给线程池管理,只需要把执行逻辑放进去就OKfor (int i = 0; i < 20; i++) {int finalI = i;executorService.execute(new Runnable() {@Overridepublic void run() {System.out.println("Thread Name: "+Thread.currentThread().getName()+" I="+ finalI);try {Thread.sleep(5*1000);} catch (InterruptedException e) {e.printStackTrace();}}});}executorService.shutdown();}
}
MyTask
public class MyTask implements Callable<String> {private Integer integer1;private Integer integer2;public MyTask(Integer integer1,Integer integer2){this.integer1 =integer1;this.integer2 =integer2;}@Overridepublic String call() throws Exception {int i = integer1 + integer2;return "Thread name:" + Thread.currentThread().getName()+" i="+i;}
}
PoolTest2
public class PoolTest2 {public static void main(String[] args) throws ExecutionException, InterruptedException {
// ExecutorService executorService1 = Executors.newCachedThreadPool();
// ExecutorService executorService2 = Executors.newFixedThreadPool(5);
// ExecutorService executorService3 = Executors.newSingleThreadExecutor();
// ScheduledExecutorService executorService4 = Executors.newScheduledThreadPool(5);ThreadPoolExecutor executorService = new ThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10), new ThreadPoolExecutor.AbortPolicy());// 执行任务-线程不用我们创建,交给线程池管理,只需要把执行逻辑放进去就OKArrayList<Future<String>> futures = new ArrayList<>();for (int i = 0; i < 20; i++) {MyTask myTask = new MyTask(3,4);Future<String> future = executorService.submit(myTask);// future.get()为myTask.call()的返回值futures.add(future);}List<String> resutlts = new ArrayList<>();for (int i = 0; i < futures.size(); i++) {String resutlt = futures.get(i).get();resutlts.add(resutlt);}System.out.println("===="+resutlts.get(19));executorService.shutdown();}
}