Java中基本线程池介绍


前言

本文章只针对Exectors去创建线程池,让大家对线程池先有点基本的了解,但是实际开发中不允许用这样的方式去创建,而是通过ThreadPoolExecutor方式(最原始的线程池创建方式,之后的文章会涉及)。

一、newFixedThreadPool

  • 定义:创建一个线程池,重用固定数量的线程,从共享无界队列中运行,使用提供的ThreadFactory在需要时创建新线程。 在任何时候,最多nThreads个线程将处于主动处理任务。 如果所有线程处于活动状态时,提交其他任务,则它们将在等待队列中直到线程可用。 如果任何线程由于在关闭之前的执行期间发生故障而终止,则如果需要执行后续任务,则新线程将占用它。 池中的线程将存在,直到它明确地被shutdown 。
  • 使用场景:适用于任务量已知,相对耗时的任务。
  • 举例加分析(代码中)
public class testCreateThreadPool {
    public static void main(String[] args)  {
        //创建固定大小为3的线程
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        for (int i = 0; i <5 ; i++) {
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"执行");
                }
            });
        }
        //shutdown三个线程,结束
        executorService.shutdown();
        /*
        运行结果:
        pool-1-thread-2执行
        pool-1-thread-3执行
        pool-1-thread-2执行
        pool-1-thread-3执行
        pool-1-thread-1执行
         */
        /*
        分析:一共只有三个线程,因此这5个任务是由这三个线程完成的
         */
    }
}

二、newCachedThreadPool

  • 定义:一个根据需要创建新线程的线程池,但在可用时将重新使用以前构造的线程。 这些池通常会提高执行许多短暂异步任务的程序的性能。 调用execute将重用以前构造的线程(如果可用)。 如果没有可用的线程,将创建一个新的线程并将其添加到该池中。 未使用六十秒的线程将被终止并从缓存中删除。 因此,长时间保持闲置的池将不会消耗任何资源
  • 使用场景:适合任务数比较密集,但每个任务执行时间较短的情况。
  • 举例加分析(代码中)
public class testCreateThreadPool {
    public static void main(String[] args) throws InterruptedException {

        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i <5 ; i++) {
            //Thread.sleep(100);//注释掉是运行结果1,不注释掉是运行结果2
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"执行");
                }
            });
        }

        /*
        运行结果1:
        pool-1-thread-4执行
        pool-1-thread-3执行
        pool-1-thread-2执行
        pool-1-thread-5执行
        pool-1-thread-1执行
        运行结果2:
        pool-1-thread-1执行
        pool-1-thread-1执行
        pool-1-thread-1执行
        pool-1-thread-1执行
        pool-1-thread-1执行
         */
        /*
        分析:
        运行结果1一共创建了5个线程,这是因为5个任务之间的间隔很短,
        第二个任务要执行时,第一个任务未完成(该任务创建的线程当前不可用)
        因此只能在创建第二个,以此类推
        运行结果2一共创建了1个线程,这是因为每个任务之间间隔了200ms,
        这个时间足够创建的线程完成任务,在下一个任务到来前处于可用状态
         */
    }
}

三、newSingleThreadExector

  • 定义:创建一个使用从无界队列运行的单个工作线程的执行程序。(注意:如果这个单个线程由于在关闭之前的执行过程中发生故障而终止,则如果需要执行后续任务,则新的线程将占用它。)任务保证顺序执行,并且不超过一个任务将被激活在任何给定的时间。
  • 使用场景:希望多个任务排队执行。因为线程数固定为1,任务数多于1时,会放入无界队列排队。任务执行完毕后,这唯一的线程也不会被释放。
  • 举例加分析(代码中)
public class testCreateThreadPool {
    public static void main(String[] args) throws InterruptedException {

        ExecutorService executorService = Executors.newSingleThreadExecutor();
        for (int i = 0; i <5 ; i++) {
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"执行");
                }
            });
        }
executorService.shutdown();
        /*
        运行结果:
        pool-1-thread-1执行
        pool-1-thread-1执行
        pool-1-thread-1执行
        pool-1-thread-1执行
        pool-1-thread-1执行
         */
        /*
        分析:
        因为该线程是单线程执行器,因此只有一个线程执行所有任务
         */
    }
}

四、newScheduledThreadPool

  • 定义:创建一个线程池,可以调度命令在给定的延迟之后运行,或定期执行
  • 使用场景:任务需要周期性或者定时执行。
  • 举例加分析(代码中)
public class testCreateThreadPool {
    //线程安全的队列
    static Queue<Integer> queue = new ConcurrentLinkedQueue<Integer>();
    static {
        for (int i = 1; i <=5 ; i++) {
            queue.add(i);
        }
    }
    public static void main(String[] args) throws InterruptedException {
        //获取时间
        SimpleDateFormat sdf=new SimpleDateFormat("hh:mm:ss");
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
        for (int i = 0; i <5 ; i++) {
            int curVal=queue.poll();
          scheduledExecutorService.schedule(new Runnable() {
              @Override
              public void run() {
                  System.out.println("在"+sdf.format(new Date())+"时,线程执行了第"+curVal+"个任务");
              }
          },curVal,TimeUnit.SECONDS);

        }
        scheduledExecutorService.shutdown();

        /*
        运行结果:
        在09:31:28时,线程执行了第1个任务
        在09:31:29时,线程执行了第2个任务
        在09:31:30时,线程执行了第3个任务
        在09:31:31时,线程执行了第4个任务
        在09:31:32时,线程执行了第5个任务
         */
        /*
        分析:
          public ScheduledFuture<?> schedule(Runnable command,
                                       long delay, TimeUnit unit);
          本例中delay为1,2,3,4,5,unit为秒,即5个任务分别延迟1,2,3,4,5秒后执行
         */
    }

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值