java线程池

1. 为什么使用线程池

1、降低资源的消耗
2、提高响应的速度
3、方便管理。
线程池可以达到:线程复用、可以控制最大并发数、管理线程的目的

2. 线程池的使用

2.1 Executors的三种方法

package pool;

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * study01
 *
 * @author : xgj
 * @description : de
 * @date : 2020-09-21 10:18
 **/
public class ThreadPool {
    public static void main(String[] args) {
        //创建只有一个线程的线程池,但是其阻塞队列长度可以达到Integer.MAX_VALUE
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        for (int i = 0; i <10 ; i++) {
            threadPool.execute(()->{
                  //输出线程名
                System.out.println(Thread.currentThread().getName());
            });
        }
        //使用完成后需要进行关闭
        threadPool.shutdown();
        
    }
}

运行截图

package pool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * study01
 *
 * @author : xgj
 * @description : de
 * @date : 2020-09-21 10:18
 **/
public class ThreadPool {
    public static void main(String[] args) {
        //创建指定个数的线程池,其阻塞队列长度可以达到Integer.MAX_VALUE
        ExecutorService threadPool = Executors.newFixedThreadPool(5);
        for (int i = 0; i <10 ; i++) {
            threadPool.execute(()->{
                //输出线程的名字
                System.out.println(Thread.currentThread().getName());
            });
        }
        //使用完成后需要进行关闭
        threadPool.shutdown();

    }
}

运行结果:

package pool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * study01
 *
 * @author : xgj
 * @description : de
 * @date : 2020-09-21 10:18
 **/
public class ThreadPool {
    public static void main(String[] args) {
        //创建个数动态添加的线程池,其数量可以达到Integer.MAX_VALUE
        ExecutorService threadPool = Executors.newCachedThreadPool();
        for (int i = 0; i <10 ; i++) {
            threadPool.execute(()->{
                //输出线程的名字
                System.out.println(Thread.currentThread().getName());
            });
        }
        //使用完成后需要进行关闭
        threadPool.shutdown();

    }
}

运行结果:

但是实际开发中最好不要通过Executors创建,而是自己通过ThreadPoolExecutor创建,这样可以自定义设定参数,策略。其实前面三种相当于默认提供的工具类:

    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

本质还是通过ThreadPoolExecutor创建的线程池。

2.2 推荐使用ThreadPoolExecutor创建线程池

    public ThreadPoolExecutor(int corePoolSize,//核心线程数 (默认会由这么多线程)
                              int maximumPoolSize,//最大核心线程数 (如果默认数量的线程不够,允许动态添加的线程数上限)
                              long keepAliveTime, //超出默认线程数的线程空闲这么长时间后销毁
                              TimeUnit unit,//超时单位
                              BlockingQueue<Runnable> workQueue,//阻塞队列
                              ThreadFactory threadFactory,//线程工厂 一般不会改变
                              RejectedExecutionHandler handler//拒绝策略  注意 不仅仅只是执行的线程,而是 最大线程数+阻塞队列的长度。
                                                                  ) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

拒接策略:

new ThreadPoolExecutor.AbortPolicy() // 直接抛出异常
new ThreadPoolExecutor.DiscardPolicy() //队列满了,直接丢弃任务,不会抛出异常! 
new ThreadPoolExecutor.DiscardOldestPolicy() //队列满了,尝试去和早的竞争,也不会抛出异常!
new ThreadPoolExecutor.CallerRunsPolicy() // 将任务交给原线程执行。 
posted @ 2020-09-21 11:00  大嘤熊  阅读(176)  评论(0编辑  收藏  举报