Java并发—线程池

什么是线程池

Java线程池实现了Java高并发的、Java多线程的、可管理的统一调度器。 java.util.concurrent.Executors 工作中最常用的和熟知的。
Executors 是线程的工厂类,方便快捷地创建多个线程池,也可以说是一个线程池地工具类。配置一个线程池是比较复杂地,尤其是对于线程池的原理不是很清楚的情况下,很有可能配置的线程池不是最优的,因此,在Executors 类里面提供了一些静态工厂,生成一些常用的线程池。常用的方法有以下三种:

  • newSingleThreadExecutor:创建一个单线程的线程池。
  • newFixedThreadPool:创建固定大小的线程池。
  • newCachedThreadPool:创建一个可缓存的线程池。
    在这里插入图片描述
    创建线程池ExecutorsDemo:
public class ExecutorsDemo {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
      ExecutorService executor = Executors.newSingleThreadExecutor();//单一线程方法
        Thread.sleep(10000L);//方便监控工具能捕获到
//    ExecutorService executor = Executors.newCachedThreadPool();
//    Thread.sleep(50000L);//方便监控工具能捕获到
//    ExecutorService executor = Executors.newFixedThreadPool(3);//固定线程方法,固定线程三个线程
//        ExecutorService executor = Executors.newFixedThreadPool(5);//固定线程五个线程
        for (int i = 0; i < 20; i++) {
            final int no = i;
            Runnable runnable = new Runnable() {
                public void run() {
                    try {
                        System.out.println("into" + no);
                        System.out.println(Thread.currentThread().getName()+"开始执行");
                        Thread.sleep(1000L);//处理数据
//                Thread.sleep(5000L);//处理数据
                        System.out.println("end" + no);
                        System.out.println(Thread.currentThread().getName()+"结束业务");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            executor.execute(runnable);//将业务交给线程来执行
        }
        executor.shutdown();//停止接收新任务,原来任务继续执行
        System.out.println("Thread Main End!");
    }
}

newSingleThreadExecutor

创建一个单线程的线程池,这个线程池只有一个线程在工作,也就是相当于单线程串行执行所以任务,如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它,此线程池保证所有任务执行顺序按照任务的提交顺序执行。

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

上面代码根据ThreadPoolExecutor创建一个LinkedBlockingQueue的一个大小的线程池,采用默认的异常策略。
在这里插入图片描述

newFixedThreadPool

固定线程方法

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}
上面代码中固定了三个线程方法,以三个线程循环执行。

在这里插入图片描述

newCachedThreadPool

可缓存线程方法,该线程遇强则强。

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}
上面代码创建了一个内核线程池。线程为零,来一个线程就在线程池里面创建一个SynchronousQueue。

在这里插入图片描述

线程池的优点

1.线程池的重用
线程的创建和销毁的开销是巨大的,而通过线程池的重用大大减少了这些不必要的开销,助于提升线程的执行速度。
2.控制线程池的并发数
并发:在某个时间段内,多个线程都处在执行和执行完毕之间;但在一个时间点上只有一个程序在运行。
并行:在某个时间段内,每个程序按照自己的独立异步的速度执行,程序之间互不干扰。
控制线程池的并发数可以有效的避免大量的线程池争夺CPU资源造成阻塞。
3.线程池可以对线程进行管理
线程池可以提供定时,定期,单线程,并发数控制等功能。

线程池的七个参数

corePoolSize 线程池中核心线程的数量
maximumPoolSize 线程池中最大线程数量
keepAliveTime 非核心线程的超时时长,当系统中非核心线程闲置时间超过keepAliveTime之后,则会被回收。如果ThreadPoolExecutor的allowCoreThreadTimeOut属性设置为true,则该参数也表示核心线程的超时时长
unit 第三个参数的单位,有纳秒、微秒、毫秒、秒、分、时、天等
workQueue 线程池中的任务队列,该队列主要用来存储已经被提交但是尚未执行的任务。存储在这里的任务是由ThreadPoolExecutor的execute方法提交来的。
threadFactory 为线程池提供创建新线程的功能,这个我们一般使用默认即可
handler 拒绝策略,当线程无法执行新任务时(一般是由于线程池中的线程数量已经达到最大数或者线程池关闭导致的),默认情况下,当线程池无法处理新线程时,会抛出一个RejectedExecutionException。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值