JAVA
浅析Java线程池
  • By刘立博
  • 2022-08-24 15:37:28
  • 403人已阅读

线程池带来的好处

 

(1)降低资源消耗

(2)提高响应速度

(3)提高线程的可管理性

 

线程池核心参数

 

corePoolSize:核心线程池大小,即始终存活的线程数

maximumPoolSize:线程池最大线程数

keepAliveTime:核心线程之外的线程最大空闲时间,超过空闲时间的线程会被释放

Util:keepAliveTime的时间单位

Handler:线程池拒绝策略

workQueue:存储待执行任务的策略

threadFactory:线程工厂,用于创建线程

 

 

线程池处理流程

提交任务后,首先会判断有无空闲的核心线程,如果没有空闲的核心线程,任务则会被添加至阻塞对列;如果阻塞对列已满,则会判断是否达到线程的最大值,如果达到了最大值,则会根据设置的饱和策略进行处理

 

线程池可选阻塞对列

 

无界对列

无存储上限的队列

    @Test
    void testLinkedBlockingQueue() {
        LinkedBlockingQueue<Integer> linkedBlockingQueue = new LinkedBlockingQueue<>();
        for (int i = 0; i < 20; i++) {
            linkedBlockingQueue.add(i);
            System.out.println("向队列添加:"+i);
        }
    }

有界队列

有存储上限的队列

    @Test
    void testArrayBlockingQueue() throws InterruptedException {
        ArrayBlockingQueue<Integer> arrayBlockingQueue = new ArrayBlockingQueue<>(10);
        for (int i = 0; i < 20; i++) {
            arrayBlockingQueue.put(i);
            System.out.println("向队列添加:"+i);
        }
    }

同步移交对列

不存储任务的队列

    @Test
    void testSynchronousQueue() throws InterruptedException {
        SynchronousQueue<Integer> synchronousQueue = new SynchronousQueue<>();

        new Thread(()->{
            System.out.println("开始提交任务");
            try {
                synchronousQueue.put(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("提交线程结束");
        }).start();

        new Thread(()->{
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("消费线程启动");
            try {
                synchronousQueue.take();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("消费线程结束");
        }).start();

        Thread.sleep(20000);
    }

线程池可选饱和策略

 

AbortPolicy 终止策略

DiscardPolicy 抛弃策略

DiscardOldestPolicy 抛弃旧任务策略

CallerRunsPolicy 调用者运行策略

 

常用线程池

通过不同的传参,可以实现不同的特性,如以下三种常用的线程池

 

线程数量无限的线程池 newCachedThreadPool

线程数量固定线程池 newFixedThreadPool

单一线程 newSingleThreadExecutor

 

向线程池提交任务

使用submit方法提交任务

    @Test
    void testThreadPool() throws ExecutionException, InterruptedException {
        ExecutorService threadPool = Executors.newCachedThreadPool();
        Future<Integer> future = threadPool.submit(()->{
            Thread.sleep(10000);
            return 100;
        });
        System.out.println(future.get());
    }

 

ShutDown和ShutDownNow的区别

ShutDown首先不再向队列中添加新的任务,待所有任务都执行完毕后再关闭线程池

ShutDownNow会立即关闭线程池