专栏首页行者常至016.多线程-线程池的四种创建方式

016.多线程-线程池的四种创建方式

版权声明:本文为博主原创文章,允许转载,请标明出处。 https://blog.csdn.net/qwdafedv/article/details/84256291

前言

为什么要用线程池

经常创建、销毁 线程,将是对系统资源的极大浪费。 因此,实际开发中我们将使用线程池来管理、复用 线程。 使用线程池,可以 1.降低资源消耗: 重复利用线程,减少创建和销毁造成的消耗。 2.提升响应速度: 任务到达,不需要创建,立即执行。 3.提高可管理型: 线程是CPU调度和分派的基本单位, 如果无限制地创建,不仅会消耗系统资源,还会降低系统稳定性。 使用线程池可以统一进行 分配、调优和监控。

线程池的分类

ThreadPoolExecutor

ThreadPoolExecutor是线程池的真正实现, 他通过构造方法的一系列参数,来构成不同配置的线程池。 常用的构造方法有下面四个

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler);
  • corePoolSize: 核心池的大小。 当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中
  • maximumPoolSize: 线程池最大线程数,它表示在线程池中最多能创建多少个线程;
  • keepAliveTime: 表示线程没有任务执行时最多保持多久时间会终止。
  • unit: 参数keepAliveTime的时间单位,有7种取值,在TimeUnit类中有7种静态属性。
  • workQueue:一个阻塞队列,提交的任务将会被放到这个队列里。
  • threadFactory:线程工厂,用来创建线程,主要是为了给线程起名字,默认工厂的线程名字:pool-1-thread-3。
  • handler:拒绝策略,当线程池里线程被耗尽,且队列也满了的时候会调用。

线程池的四种创建方式

Java通过Executors(jdk1.5并发包)提供四种线程池,分别为:

  • newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 案例演示:
  • newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
  • newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
  • newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

newCachedThreadPool

创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程, 若无可回收,则新建线程。

package cn.qbz.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test111907 {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            final int temp = i;
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "   i=" + temp);
                }
            });
        }
    }
}
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

newFixedThreadPool

创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

package cn.qbz.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test111907 {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 10; i++) {
            final int temp = i;
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "   i=" + temp);
                }
            });
        }
    }
}
    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

newScheduledThreadPool

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

package cn.qbz.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Test111907 {
    public static void main(String[] args) {
        final long begin = System.currentTimeMillis();
        ExecutorService executorService = Executors.newScheduledThreadPool(3);
        for (int i = 0; i < 10; i++) {
            final int temp = i;
            final long time = begin;
            executorService.schedule(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "   i=" + temp + "   time=" + (System.currentTimeMillis() - time));
                }
            }, 5, TimeUnit.SECONDS);
        }
    }
}
    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
              new DelayedWorkQueue());
    }

newSingleThreadExecutor

创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务, 保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

package cn.qbz.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Test111907 {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 10; i++) {
            final int temp = i;
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "   i=" + temp);
                }
            });
        }
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 003.多线程-主线程、守护线程、用户线程的区别

    守护线程: 主要是指 在进程中,为主线程提供一种通用服务的线程。 比如 gc线程 因为,主线程一旦结束或者销毁, 守护线程没有了守护对象, 也将同步进...

    qubianzhong
  • 005.多线程-线程的生命周期

    新建状态: 当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。 如:ThreadTest thread2 = new ThreadT...

    qubianzhong
  • 001.多线程-进程与线程的区别

    什么是进程?顾名思义,就是进行中的程序,也就是运行中的程序。我们打开电脑的任务管理器可以看到:

    qubianzhong
  • jstack的使用

    有些时候我们需要查看下jvm中的线程执行情况,比如,发现服务器的CPU的负载突然增高了、出现了死锁、死循环等,我们该如何分析呢?由于程序是正常运行的,没有任何的...

    乐心湖
  • 【面试宝典】Java之线程一如何开启线程

    面试官:大四是吧? 小白:是的,学校大四没有课,只有毕业设计,就想着提前出来锻炼锻炼。 面试官:想法很好,那咱们开始吧,知道线程吧! 小白:嗯,线程是CPU执行...

    程序员互动联盟
  • Java学习内存模型以及线程安全的可见性问题(八)

    java // 线程1 a = d; b = 2 // 线程2 c = a; d =3 //重排序后 //线程1 b = 2 ; a =d; //线程2 d =...

    IT故事会
  • 第二十五天 多线程-常用方法&线程池【悟空教程】

    System.out.println(getName() + " ==== " + i );

    Java帮帮
  • (69) 线程的中断 / 计算机程序的思维逻辑

    本节主要讨论一个问题,如何在Java中取消或关闭一个线程? 取消/关闭的场景 我们知道,通过线程的start方法启动一个线程后,线程开始执行run方法,run...

    swiftma
  • 高并发编程学习(2)——线程通信详解

    上一篇文章我们提到一个应用可以创建多个线程去执行不同的任务,如果这些任务之间有着某种关系,那么线程之间必须能够通信来协调完成工作。

    我没有三颗心脏
  • 高并发编程学习(2)——线程通信详解

    上一篇文章我们提到一个应用可以创建多个线程去执行不同的任务,如果这些任务之间有着某种关系,那么线程之间必须能够通信来协调完成工作。

    乔戈里

扫码关注云+社区

领取腾讯云代金券