目录
- 线程池
- 什么是线程池?
- 为什么用线程池?
- 线程池原理
- 常见四种线程池和自定义线程池
线程池
什么是线程池?
池化技术
为什么用线程池?
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());
// 执行任务-线程不用我们创建,交给线程池管理,只需要把执行逻辑放进去就OK
for (int i = 0; i < 20; i++) {
int finalI = i;
executorService.execute(new Runnable() {
@Override
public 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;
}
@Override
public 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());
// 执行任务-线程不用我们创建,交给线程池管理,只需要把执行逻辑放进去就OK
ArrayList<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();
}
}