赞
踩
难易程度:☆☆☆
出现频率:☆☆☆☆
线程池核心参数主要参考ThreadPoolExecutor这个类的7个参数的构造函数
工作流程
1,任务在提交的时候,首先判断核心线程数是否已满,如果没有满则直接添加到工作线程执行
2,如果核心线程数满了,则判断阻塞队列是否已满,如果没有满,当前任务存入阻塞队列
3,如果阻塞队列也满了,则判断线程数是否小于最大线程数,如果满足条件,则使用临时线程执行任务
如果核心或临时线程执行完成任务后会检查阻塞队列中是否有需要执行的线程,如果有,则使用非核心线程执行任务
4,如果所有线程都在忙着(核心线程+临时线程),则走拒绝策略
拒绝策略:
1.AbortPolicy:直接抛出异常,默认策略;
2.CallerRunsPolicy:用调用者所在的线程来执行任务;
3.DiscardOldestPolicy:丢弃阻塞队列中靠最前的任务,并执行当前任务;
4.DiscardPolicy:直接丢弃任务;
参考代码:
- public class TestThreadPoolExecutor {
-
- static class MyTask implements Runnable {
- private final String name;
- private final long duration;
-
- public MyTask(String name) {
- this(name, 0);
- }
-
- public MyTask(String name, long duration) {
- this.name = name;
- this.duration = duration;
- }
-
- @Override
- public void run() {
- try {
- LoggerUtils.get("myThread").debug("running..." + this);
- Thread.sleep(duration);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
-
- @Override
- public String toString() {
- return "MyTask(" + name + ")";
- }
- }
-
- public static void main(String[] args) throws InterruptedException {
- AtomicInteger c = new AtomicInteger(1);
- ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(2);
- ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
- 2,
- 3,
- 0,
- TimeUnit.MILLISECONDS,
- queue,
- r -> new Thread(r, "myThread" + c.getAndIncrement()),
- new ThreadPoolExecutor.AbortPolicy());
- showState(queue, threadPool);
- threadPool.submit(new MyTask("1", 3600000));
- showState(queue, threadPool);
- threadPool.submit(new MyTask("2", 3600000));
- showState(queue, threadPool);
- threadPool.submit(new MyTask("3"));
- showState(queue, threadPool);
- threadPool.submit(new MyTask("4"));
- showState(queue, threadPool);
- threadPool.submit(new MyTask("5",3600000));
- showState(queue, threadPool);
- threadPool.submit(new MyTask("6"));
- showState(queue, threadPool);
- }
-
- private static void showState(ArrayBlockingQueue<Runnable> queue, ThreadPoolExecutor threadPool) {
- try {
- Thread.sleep(300);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- List<Object> tasks = new ArrayList<>();
- for (Runnable runnable : queue) {
- try {
- Field callable = FutureTask.class.getDeclaredField("callable");
- callable.setAccessible(true);
- Object adapter = callable.get(runnable);
- Class<?> clazz = Class.forName("java.util.concurrent.Executors$RunnableAdapter");
- Field task = clazz.getDeclaredField("task");
- task.setAccessible(true);
- Object o = task.get(adapter);
- tasks.add(o);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- LoggerUtils.main.debug("pool size: {}, queue: {}", threadPool.getPoolSize(), tasks);
- }
-
- }

难易程度:☆☆☆
出现频率:☆☆☆
workQueue - 当没有空闲核心线程时,新来任务会加入到此队列排队,队列满会创建救急线程执行任务
比较常见的有4个,用的最多是ArrayBlockingQueue和LinkedBlockingQueue
1.ArrayBlockingQueue:基于数组结构的有界阻塞队列,FIFO。
2.LinkedBlockingQueue:基于链表结构的有界阻塞队列,FIFO。
3.DelayedWorkQueue :是一个优先级队列,它可以保证每次出队的任务都是当前队列中执行时间最靠前的
4.SynchronousQueue:不存储元素的阻塞队列,每个插入操作都必须等待一个移出操作。
ArrayBlockingQueue的LinkedBlockingQueue区别
LinkedBlockingQueue | ArrayBlockingQueue |
---|---|
默认无界,支持有界 | 强制有界 |
底层是链表 | 底层是数组 |
是懒惰的,创建节点的时候添加数据 | 提前初始化 Node 数组 |
入队会生成新 Node | Node需要是提前创建好的 |
两把锁(头尾) | 一把锁 |
左边是LinkedBlockingQueue加锁的方式,右边是ArrayBlockingQueue加锁的方式
难易程度:☆☆☆☆
出现频率:☆☆☆
在设置核心线程数之前,需要先熟悉一些执行线程池执行任务的类型
一般来说:文件读写、DB读写、网络请求等
推荐:核心线程数大小设置为2N+1 (N为计算机的CPU核数)
一般来说:计算型代码、Bitmap转换、Gson转换等
推荐:核心线程数大小设置为N+1 (N为计算机的CPU核数)
java代码查看CPU核数
参考回答:
① 高并发、任务执行时间短 -->( CPU核数+1 ),减少线程上下文的切换
② 并发不高、任务执行时间长
③ 并发高、业务执行时间长,解决这种类型任务的关键不在于线程池而在于整体架构的设计,看看这些业务里面某些数据是否能做缓存是第一步,增加服务器是第二步,至于线程池的设置,设置参考(2)
难易程度:☆☆☆
出现频率:☆☆☆
在java.util.concurrent.Executors类中提供了大量创建连接池的静态方法,常见就有四种
- java public class FixedThreadPoolCase {
- static class FixedThreadDemo implements Runnable{
- @Override
- public void run() {
- String name = Thread.currentThread().getName();
- for (int i = 0; i < 2; i++) {
- System.out.println(name + ":" + i);
- }
- }
- }
-
- public static void main(String[] args) throws InterruptedException {
- //创建一个固定大小的线程池,核心线程数和最大线程数都是3
- ExecutorService executorService = Executors.newFixedThreadPool(3);
-
- for (int i = 0; i < 5; i++) {
- executorService.submit(new FixedThreadDemo());
- Thread.sleep(10);
- }
-
- executorService.shutdown();
- }
- }

- java public class NewSingleThreadCase {
- static int count = 0;
-
- static class Demo implements Runnable {
- @Override
- public void run() {
- count++;
- System.out.println(Thread.currentThread().getName() + ":" + count);
- }
- }
-
- public static void main(String[] args) throws InterruptedException {
- //单个线程池,核心线程数和最大线程数都是1
- ExecutorService exec = Executors.newSingleThreadExecutor();
-
- for (int i = 0; i < 10; i++) {
- exec.execute(new Demo());
- Thread.sleep(5);
- }
- exec.shutdown();
- }
- }

- java public class CachedThreadPoolCase {
- static class Demo implements Runnable {
- @Override
- public void run() {
- String name = Thread.currentThread().getName();
- try {
- //修改睡眠时间,模拟线程执行需要花费的时间
- Thread.sleep(100);
-
- System.out.println(name + "执行完了");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
-
- public static void main(String[] args) throws InterruptedException {
- //创建一个缓存的线程,没有核心线程数,最大线程数为Integer.MAX_VALUE
- ExecutorService exec = Executors.newCachedThreadPool();
- for (int i = 0; i < 10; i++) {
- exec.execute(new Demo());
- Thread.sleep(1);
- }
- exec.shutdown();
- }
- }

- java public class ScheduledThreadPoolCase {
- static class Task implements Runnable {
- @Override
- public void run() {
- try {
- String name = Thread.currentThread().getName();
-
- System.out.println(name + ", 开始:" + new Date());
- Thread.sleep(1000);
- System.out.println(name + ", 结束:" + new Date());
-
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
-
- public static void main(String[] args) throws InterruptedException {
- //按照周期执行的线程池,核心线程数为2,最大线程数为Integer.MAX_VALUE
- ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);
- System.out.println("程序开始:" + new Date());
-
- /**
- * schedule 提交任务到线程池中
- * 第一个参数:提交的任务
- * 第二个参数:任务执行的延迟时间
- * 第三个参数:时间单位
- */
- scheduledThreadPool.schedule(new Task(), 0, TimeUnit.SECONDS);
- scheduledThreadPool.schedule(new Task(), 1, TimeUnit.SECONDS);
- scheduledThreadPool.schedule(new Task(), 5, TimeUnit.SECONDS);
-
- Thread.sleep(5000);
-
- // 关闭线程池
- scheduledThreadPool.shutdown();
-
- }
- }

难易程度:☆☆☆
出现频率:☆☆☆
参考阿里开发手册《Java开发手册-嵩山版》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。