Java 线程池

一、四种线程池

Java通过Executors提供四种线程池,分别为:

1、newSingleThreadExecutor 单一线程的线程池

创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。通过Executors中的newSingleThreadExecutor方法来创建,在这个线程池中只有一个核心线程,对于任务队列没有大小限制,也就意味着这一个任务处于活动状态时,其他任务都会在任务队列中排队等候依次执行。

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

newSingleThreadExecutor将所有的外界任务统一到一个线程中支持,所以在这个任务执行之间我们不需要处理线程同步的问题。

   ExecutorService signalPool = Executors.newSingleThreadExecutor();
                for (int i=0;i<10;i++){
                    final int i1 = i;
                    try{
                        Thread.sleep(1 * 1000);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                    signalPool.execute(new Runnable() {
                        @Override
                        public void run() {
                            Log.d("BOB",""+Thread.currentThread().getName() +"执行" +i1);
                        }
                    });
                }

2、newFixedThreadPool 定长线程池

在这个线程池中 所容纳最大的线程数就是我们设置的核心线程数。 如果线程池的线程处于空闲状态的话,它们并不会被回收,除非是这个线程池被关闭。如果所有的线程都处于活动状态的话,新任务就会处于等待状态,直到有线程空闲出来。

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

由于newFixedThreadPool只有核心线程,并且这些线程都不会被回收,也就是 它能够更快速的响应外界请求 。从下面的newFixedThreadPool方法的实现可以看出,newFixedThreadPool只有核心线程,并且不存在超时机制,采用LinkedBlockingQueue,所以对于任务队列的大小也是没有限制的。

  ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
                for (int i=0;i<10;i++){
                    final int i1 = i;
                    try {
                        Thread.sleep(1*1000);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                    fixedThreadPool.execute(new Runnable() {
                        @Override
                        public void run() {
                            Log.d("BOB",""+Thread.currentThread().getName() +"执行" +i1);

                        }
                    });
                }

3、newScheduledThreadPool

创建一个可定期或者延时执行任务的定长线程池,支持定时及周期性任务执行。

  public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE,
              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
              new DelayedWorkQueue());
    }

它的核心线程数是固定的,对于非核心线程几乎可以说是没有限制的,并且当非核心线程处于限制状态的时候就会立即被回收。

{
                ScheduledExecutorService schedulePool = Executors.newScheduledThreadPool(3);

                Runnable r1 = new Runnable() {
                    @Override
                    public void run() {
                        Log.d("BOB","延迟2秒执行 :"+" r1 "+Thread.currentThread().getName());
                    }
                };
                schedulePool.schedule(r1,2, TimeUnit.SECONDS);

                Runnable r2 = new Runnable() {
                    @Override
                    public void run() {
                        Log.d("BOB","延迟3秒执行 :"+" r2 "+Thread.currentThread().getName());
                    }
                };
                schedulePool.schedule(r2,3,TimeUnit.SECONDS);

                Runnable r3 = new Runnable() {
                    @Override
                    public void run() {
                        Log.d("BOB","延迟1秒执行 :"+" r3 "+Thread.currentThread().getName());
                    }
                };
                for (int i = 0; i<4; i++){
                    schedulePool.schedule(r3,1,TimeUnit.SECONDS);
                }

            }

4、newCachedThreadPoo 缓存线程池

创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。如果线程池的规模超过了处理需求,将自动回收空闲线程,而当需求增加时,则可以自动添加新线程,线程池的规模不存在任何限制

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

通过s上面的newCachedThreadPool方法在这里我们可以看出它的 核心线程数为0, 线程池的最大线程数Integer.MAX_VALUE。而Integer.MAX_VALUE是一个很大的数,也差不多可以说 这个线程池中的最大线程数可以任意大。

当线程池中的线程都处于活动状态的时候,线程池就会创建一个新的线程来处理任务。该线程池中的线程超时时长为60秒,所以当线程处于闲置状态超过60秒的时候便会被回收。 这也就意味着若是整个线程池的线程都处于闲置状态超过60秒以后,在newCachedThreadPool线程池中是不存在任何线程的,所以这时候它几乎不占用任何的系统资源。

对于newCachedThreadPool他的任务队列采用的是SynchronousQueue,上面说到在SynchronousQueue内部没有任何容量的阻塞队列。SynchronousQueue内部相当于一个空集合,我们无法将一个任务插入到SynchronousQueue中。所以说在线程池中如果现有线程无法接收任务,将会创建新的线程来执行任务。

案例代码

 ExecutorService catchThreadPool = Executors.newCachedThreadPool();
        for (int i=0 ;i<10;i++){
            final int i1 = i;
            try{
                Thread.sleep(1 * 1000);
            }catch (Exception e){
                e.printStackTrace();
            }
            catchThreadPool.execute(new Runnable() {
                                        @Override
                                        public void run() {
                                            Log.d("BOB",""+Thread.currentThread().getName() +"执行" +i1);
                                        }
                                    }
            );
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值