java线程池核心构造

为什么需要线程池

  1. 因为如果不使用线程池的化,就需要每次使用线程的时候创建并销毁线程,造成了资源的浪费。而使用线程池对线程进行管理,线程只需要一次性创建并可以进行重复的使用,并且还可以根据需要调整线程池的大小来执行相应的方法。

JDK提供的线程池

在这里插入图片描述

线程池的使用

  1. 线程池的种类
    • newFixedThreadPool
      • 说明: 生成固定大小的线程池,执行任务时始终是这10个线程进行任务的执行。
      • 结构:
        public static ExecutorService newFixedThreadPool(int nThreads) {
                return new ThreadPoolExecutor(nThreads, nThreads,
                                              0L, TimeUnit.MILLISECONDS,
                                              new LinkedBlockingQueue<Runnable>());
        }
        
    • newSingleThreadExecutor
      • 说明:生成只有一个线程的线程执行器,不管如何执行任务都是单线程进行。
      • 结构:
        public static ExecutorService newSingleThreadExecutor() {
            return new FinalizableDelegatedExecutorService
                (new ThreadPoolExecutor(1, 1,
                                        0L, TimeUnit.MILLISECONDS,
                                        new LinkedBlockingQueue<Runnable>()));
         }
        
    • newCacheedThreadPool
      • 带缓冲的线程池,根据实际需要创建对应的数量的线程,长时间不用线程会进行自然的消亡,其最小的核心线程数为0。
      • 结构:
        public static ExecutorService newCachedThreadPool() {
            return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                          60L, TimeUnit.SECONDS,
                                          new SynchronousQueue<Runnable>());
        }
        
    • newScheduledThreadPool
      • 说明:对线程在自定义时间内进行定时执行。
      • 结构:
            public ScheduledThreadPoolExecutor(int corePoolSize) {
                super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
                      new DelayedWorkQueue());
            }
        
      • API:
        public class ScheduledThreadPoolTest {
        
            public static void main(String[] args) {
        
                final  ThreadA tda=new ThreadA();
        
                final  ThreadB tdb=new ThreadB();
        
                final  ThreadC tdc=new ThreadC();
                
                ScheduledExecutorService exec=Executors.newScheduledThreadPool(5);
        
                System.out.println("开启延时任务执行,执行时间:"+getCurrentDate());
                //在自定义时间后延时执行线程
                exec.schedule(tda,1, TimeUnit.SECONDS);
        
                System.out.println("开启延时定时任务执行,执行时间:"+getCurrentDate());
                //在自定义时间A后延时执行线程,并每隔自定义时间B后轮询执行线程。
                exec.scheduleAtFixedRate(tdb,1,2,TimeUnit.SECONDS);
        
                System.out.println("开启延时(定时加线程执行时间)任务执行,执行时间:"+getCurrentDate());
                //在自定义时间A后延时执行线程,并没隔自定义时间B+线程本身执行时间轮询执行线程。
                exec.scheduleWithFixedDelay(tdc,1,2,TimeUnit.SECONDS);
        
                try {
        
                     TimeUnit.SECONDS.sleep(15);
        
                     exec.shutdown();
        
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        
            }
        
            public static String getCurrentDate(){
        
                Date date=new Date();
        
                SimpleDateFormat sdf=new SimpleDateFormat("HH:mm:ss");
        
                return sdf.format(date);
        
            }
        
        }
        
        class ThreadA implements Runnable{
        
            public void run() {
        
                System.out.println("ThreadA,执行时间:"+ScheduledThreadPoolTest.getCurrentDate());
        
            }
        
        }
        
        class ThreadB implements Runnable{
        
            public void run() {
        
                try {
                    TimeUnit.SECONDS.sleep(3);
        
                } catch (InterruptedException e) {
        
                    e.printStackTrace();
                }
        
                System.out.println("ThreadB,执行时间:"+ScheduledThreadPoolTest.getCurrentDate());
        
            }
        
        }
        
        class ThreadC implements Runnable{
        
            public void run() {
        
                try {
                    TimeUnit.SECONDS.sleep(3);
        
                } catch (InterruptedException e) {
        
                    e.printStackTrace();
                }
        
                System.out.println("ThreadC,执行时间:"+ScheduledThreadPoolTest.getCurrentDate());
        
            }
        
        }
        
        执行结果:
        开启延时任务执行,执行时间:14:44:29
        开启延时定时任务执行,执行时间:14:44:29
        开启延时(定时加线程执行时间)任务执行,执行时间:14:44:29
        ThreadA,执行时间:14:44:30
        ThreadB,执行时间:14:44:33
        ThreadC,执行时间:14:44:33
        ThreadB,执行时间:14:44:36
        ThreadC,执行时间:14:44:38
        ThreadB,执行时间:14:44:39
        ThreadB,执行时间:14:44:42
        ThreadC,执行时间:14:44:43
        ThreadB,执行时间:14:44:45
        

线程池的共性

  1. 都是通过ThreadPoolExecutor进行线程池的创建而来;
    public ThreadPoolExecutor(int corePoolSize,
    			                       int maximumPoolSize,
    			                       long keepAliveTime,
    			                       TimeUnit unit,
    			                       BlockingQueue<Runnable> workQueue) {
    			    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
    			         Executors.defaultThreadFactory(), defaultHandler);
    			 }
    
  2. 说明:线程池的创建中需要一个corePoolSize(核心线程数,也就是最小线程数),maximumPoolSize(最大线程数),keepAliveTime(线程最大无响应时间,当线程没有使用的话就进行销毁,一直到只剩核心线程数大小为止),TimeUnit (时间单位),BlockingQueue(任务队列),而之后还有两个参数如果没有必要的情况下就会选择默认的第一个是线程的默认生产工厂defaultThreadFactory,之后的则是默认的拒绝策略defaultHandler,之后会讲到这个拒绝策略的详情。
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值