【线程池有哪几种创建方式,能详细的说下吗?俩种方式、7种方法?以及案例演示过程】

一.知识回顾

上一篇文章我们一起学习了关于【线程池的使用规范、线程池的7个参数、4种拒绝策略、线程池的5种状态、线程池的执行流程】,接下来我们来学习一下:【线程池有哪几种创建方式,能详细的说下吗?俩种方式、7种方法?以及案例演示过程】

【线程池有哪几种创建方式,能详细的说下吗?俩种方式、7种方法?以及案例演示过程】_第1张图片

二.线程池有哪几种创建方式,能详细的说下吗?

2.1 俩种方式、7种方法

线程池的创建方法总共有 7 种(其中 6 种是通过 Executors 创建的,1 种是通过ThreadPoolExecutor 创建的,但总体来说可分为 2 类):

  1. 通过 ThreadPoolExecutor 创建的线程池;
  2. 通过 Executors 创建的线程池(不推荐使用)。

【线程池有哪几种创建方式,能详细的说下吗?俩种方式、7种方法?以及案例演示过程】_第2张图片

2.2 通过 ThreadPoolExecutor 创建的线程池

  1. ThreadPoolExecutor:最原始的创建线程池的方式,它包含了 7 个参数可供设置,上篇文章我讲到了一些基本概念,地址在这里,不会的同学先补一下相关的知识。
    【线程池的使用规范、线程池的7个参数、4种拒绝策略、线程池的5种状态、线程池的执行流程】

2.3 通过 Executors 创建的线程池

  1. Executors.newFixedThreadPool:创建一个固定大小的线程池,可控制并发的线程数,超出的线程会在队列中等待;
  2. Executors.newCachedThreadPool:创建一个可缓存的线程池,若线程数超过处理所需,缓存一段时间后会回收,若线程数不够,则新建线程;
  3. Executors.newSingleThreadExecutor:创建单个线程数的线程池,它可以保证先进先出的执行顺序;
  4. Executors.newScheduledThreadPool:创建一个可以执行延迟任务的线程池;
  5. Executors.newSingleThreadScheduledExecutor:创建一个单线程的可以执行延迟任务的线程池;
  6. Executors.newWorkStealingPool:创建一个抢占式执行的线程池,任务执行顺序不确定。JDK 8 添加

三.实战演示每种线程池创建的案例

3.1 通过 ThreadPoolExecutor 创建的线程池

3.1.1 Executors.newFixedThreadPool

创建一个固定大小的线程池,可控制并发的线程数,超出的线程会在队列中等待。
案例代码如下:

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

public class Main {
    public static void main(String[] args) {
        fixedThreadPool();
    }

    public static void fixedThreadPool() {
        // 创建固定个数大小的线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(3);

        // 创建任务
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("当前任务已经被线程"+Thread.currentThread().getName()+"执行了");
            }
        };

        // 补充一下:执行任务的方法有两种:submit 和 execute
        // 执行方式 1:submit
        threadPool.submit(runnable);
        // 执行方式 2:execute
        threadPool.execute(runnable);
    }
}

运行结果如下:
【线程池有哪几种创建方式,能详细的说下吗?俩种方式、7种方法?以及案例演示过程】_第3张图片

3.1.2 Executors.newCachedThreadPool

创建一个可缓存的线程池,若线程数超过处理所需,缓存一段时间后会回收,若线程数不够,则新建线程;

案例代码如下:

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

public class Main {
    public static void main(String[] args) {
        cachedThreadPool();
    }

    public static void cachedThreadPool() {
        // 创建线程池
        ExecutorService threadPool = Executors.newCachedThreadPool();
        // 执行任务
        for (int i = 0; i < 10; i++) {
            threadPool.execute(() -> {
                System.out.println("当前任务已经被线程"+Thread.currentThread().getName()+"执行了");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    }
}

运行结果如下:
【线程池有哪几种创建方式,能详细的说下吗?俩种方式、7种方法?以及案例演示过程】_第4张图片

3.1.3 Executors.newSingleThreadExecutor

创建单个线程数的线程池,它可以保证先进先出的执行顺序;

案例代码如下:

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

public class Main {
    public static void main(String[] args) {
        singleThreadExecutor();
    }
    public static void singleThreadExecutor() {
        // 创建线程池
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        // 执行任务
        for (int i = 0; i < 10; i++) {
            final int id = i;
            threadPool.execute(() -> {
                System.out.println("线程"+Thread.currentThread().getName()+"执行了此时的任务:"+id);
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    }
}

运行结果如下:
【线程池有哪几种创建方式,能详细的说下吗?俩种方式、7种方法?以及案例演示过程】_第5张图片

3.1.4 Executors.newScheduledThreadPool

创建一个可以执行延迟任务的线程池。

案例代码如下:

import java.time.LocalDateTime;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Main {
    public static void main(String[] args) {
        scheduledThreadPool();
    }
    public static void scheduledThreadPool() {
        // 创建线程池
        ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(5);
        // 添加定时执行任务(3s 后执行)
        System.out.println("线程池执行添加任务的操作,此时时间为:" + LocalDateTime.now());
        threadPool.schedule(() -> {
            System.out.println("线程池执行运行任务的操作,此时时间为:" + LocalDateTime.now());
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, 3, TimeUnit.SECONDS);
    }
}

运行结果如下:
【线程池有哪几种创建方式,能详细的说下吗?俩种方式、7种方法?以及案例演示过程】_第6张图片

3.1.5 Executors.newSingleThreadScheduledExecutor

创建一个单线程的可以执行延迟任务的线程池;

案例代码如下:

import java.time.LocalDateTime;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Main {
    public static void main(String[] args) {
        SingleThreadScheduledExecutor();
    }

    public static void SingleThreadScheduledExecutor() {
        // 创建线程池
        ScheduledExecutorService threadPool = Executors.newSingleThreadScheduledExecutor();
        // 添加定时执行任务(5s 后执行)
        System.out.println("线程池执行添加任务的操作,此时时间为:" + LocalDateTime.now());
        threadPool.schedule(() -> {
            System.out.println("线程池执行运行任务的操作,此时时间为:" + LocalDateTime.now());
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, 5, TimeUnit.SECONDS);
    }
}

运行结果如下:
【线程池有哪几种创建方式,能详细的说下吗?俩种方式、7种方法?以及案例演示过程】_第7张图片

3.1.6 Executors.newWorkStealingPool

创建一个抢占式执行的线程池,任务执行顺序不确定。JDK 8 添加

案例代码如下:

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

public class Main {
    public static void main(String[] args) {
        workStealingPool();
    }

    public static void workStealingPool() {
        // 创建线程池
        ExecutorService threadPool = Executors.newWorkStealingPool();
        // 执行任务
        for (int i = 0; i < 10; i++) {
            final int id = i;
            threadPool.execute(() -> {
                System.out.println("线程"+Thread.currentThread().getName()+"执行了此时的任务:"+id);
            });
        }
        // 确保线程池中的任务执行完成
        while (!threadPool.isTerminated()) {

        }
    }
}

运行结果如下:
【线程池有哪几种创建方式,能详细的说下吗?俩种方式、7种方法?以及案例演示过程】_第8张图片

3.2 通过 Executors 创建的线程池

案例实现代码

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Main {
    public static void main(String[] args) {
        // 创建线程池
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(4, 8, 100, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
        // 执行任务
        for (int i = 0; i < 10; i++) {
            final int id = i;
            threadPool.execute(() -> {
                System.out.println("线程"+Thread.currentThread().getName()+"执行了此时的任务:"+id);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    }
}

运行结果如下:
【线程池有哪几种创建方式,能详细的说下吗?俩种方式、7种方法?以及案例演示过程】_第9张图片

四.总结

这篇文章我们学习了以下的内容:

  1. 线程池有哪几种创建方式
  2. 俩种方式、7种方法以及案例演示过程

学习编程一定要动手实操,先学习别人的东西,熟练了再演化为自己的知识。

我是硕风和炜,我们下篇文章见哦。

【线程池有哪几种创建方式,能详细的说下吗?俩种方式、7种方法?以及案例演示过程】_第10张图片

你可能感兴趣的:(多线程与高并发,java,线程池,面试,编程语言,Java)