多线程(二)线程池的创建

什么是线程池?

线程池就是提前创建一定线程,放入队列中,根据默认的优先级执行任务,处理完线程不会销毁,而是等待下一个任务。

线程池的优点是什么?为什么要用线程池?

减少线程创建和销毁的消耗,提高线程复用率。频繁创建线程就要考虑用线程池了。

优点也是缺点,线程空闲也会一直占用内存。

说说常用线程池

Java中有三个比较常用的线程池,分别是FixedThreadPool,SingleThreadExecutor,CachedThreadPool。

FixedThreadPool是一个线程数固定的线程池,当这个线程池被创建的时候,池里的线程数就已经固定了。当需要运行的线程数量大体上变化不大时,适合使用这种线程池。固定数量还有一个好处,它可以一次性支付高昂的创建线程的开销,之后再使用的时候就不再需要这种开销。执行顺序:LinkedBlockingQueue   FIFO

SingleThreadExecutor是一个线程数量为1的线程池,所有提交的这个线程池的任务都会按照提交的先后顺序排队执行。单个线程执行有个好处:由于任务之间没有并发执行,因此提交到线程池种的任务之间不会相互干扰。程序执行的结果更具有确定性。

CachedThreadPool是一个和缓存有关的线程池,每次有任务提交到线程池的时候,如果池中没有空闲的线程,线程池就会为这个任务创建一个线程,如果有空闲的线程,就会使用已有的空闲线程执行任务。有的人可能会有个疑惑:这样线程不就越来越多了吗?其实不是的,这个线程池还有一个销毁机制,如果一个线程60秒之内没有被使用过,这个线程就会被销毁,这样就节省了很多资源。CachedThreadPool是一个比较通用的线程池,它在多数情况下都能表现出优良的性能。以后编码的时候,遇事不决,用缓存(线程池)。

阻塞队列:

newFixedThreadPool  线程池创建固定数量的线程,从共享无界队列(Integer.MAX_VALUE)中运行。
   无界队列:LinkedBlockingQueue
   newCachedThreadPool 缓存线程池,根据需要创建线程。
    同步队列:SynchronousQueue
    newSingleThreadExecutor()  单个线程的线程池。
     无界队列:LinkedBlockingQueue
    newScheduledThreadPool  周期线程池,可定时执行。
    延迟工作队列:DelayedWorkQueue
    newSingleThreadScheduledExecutor  单个线程周期线程池。
  延迟工作队列:DelayedWorkQueue

 

线程池的创建

1.直接用Executors(阿里开发手册不建议,因为内部细节不直观)

//Runable
ExecutorService executorService = Executors.newFixedThreadPool(3);//创建定长为3的线程池
executorService.execute(new MyThread());//提交任务到线程池
executorService.shutdown();//关闭线程池

//或者 Callable 

 /* ExecutorService executorService = Executors.newFixedThreadPool(3);
        Future<String> future = executorService.submit(new ExcutorsCallable());
        try {
            String value = future.get();
            System.out.println("----------------" + value);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        executorService.shutdown();
*/

2. ThreadPoolExecutor

ExecutorService executorService1 =	new ThreadPoolExecutor(3,//池大小
                   3,//最大线程数
				0L,//线程池中线程空闲时,线程存活的时间,任务多时,可以调大该参数
 TimeUnit.MILLISECONDS,//时间单位 毫秒
				new LinkedBlockingQueue<Runnable>()  //任务队列执行策略
);

共7个参数:核心线程大小、最大线程数、非核心线程超时时间、单位、阻塞队列、线程工厂、拒绝策略handle 

如何配置线程池大小?

  如果是CPU密集型任务,就需要尽量压榨CPU,参考值可以设为 NCPU+1

  如果是IO密集型任务,参考值可以设置为2*NCPU

  当然,这只是一个参考值,具体的设置还需要根据实际情况进行调整,比如可以先将线程池大小设置为参考值,再观察任务运行情况和系统负载、资源利用率来进行适当调整。

IO密集型比如:数据库操作

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值