java创建线程池的方法

本文介绍了Java中线程池的各种实现,包括ThreadPoolExecutor的核心功能和构造参数,如核心线程数、最大线程数、阻塞队列类型等。详细讲解了FixedThreadPool、CachedThreadPool、ScheduledThread、SingleThreadExecutor和SingleThreadScheduledExecutor的区别,以及NewWorkStealingPool的抢占式执行特点。
摘要由CSDN通过智能技术生成

简介

线程池是一种用于管理和重用线程的机制,它可以有效地管理线程的创建和销毁,减少线程创建和销毁的开销,并且能够控制并发线程数量,避免资源耗尽和系统过载。Java 提供了java.util.concurrent 包来支持线程池的实现。

1.ThreadPoolExecutor

ThreadPoolExecutor是一种很常用的线程池创建方法。

例如:

ThreadPoolExecutor threadPool = new ThreadPoolExecutor();

其构造方法可以有7个参数,分别为:

corePoolSize:核心线程数

maximumPoolSize:最大线程数

keepAliveTime:最大线程数可以存活的时间,单位有秒,分,小时等。

workQueue:阻塞队列,当线程池满时用来存储线程池等待执行的任务,均为线程安全,其有7种类型。

  • ArrayBlockingQueue:数组组成的有界阻塞队列。
  • LinkedBlockingQueue:链表组成的有界阻塞队列。
  • SynchronousQueue:不存储元素的阻塞队列,即直接提交给线程不保持它们。
  • PriorityBlockingQueue:支持优先级排序的无界阻塞队列。
  • DelayQueue:使用优先级队列实现的无界阻塞队列,只有在延迟期满时才能从中提取元素
  • LinkedTransferQueue:链表组成的无界阻塞队列。
  • LinkedBlockingDeque:链表组成的双向阻塞队列。

threadFactory:线程工厂,主要用来创建线程。

handler:拒绝策略,拒绝处理任务时的策略,有四种类型(默认为 AbortPolicy)

  • AbortPolicy:拒绝并抛出异常
  • DiscardPolicy:忽略并抛弃当前任务。
  • DiscardOldestPolicy:抛弃队列头部(最旧)的一个任务,并执行当前任务。
  • CallerRunsPolicy:使用当前调用的线程来执行此任务。

例子:

    public static void create01(){
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 15, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(20));
        for (int i = 0; i < 5; i++) {
            threadPool.execute(() -> {
                System.out.println("当前线程名为:" + Thread.currentThread().getName());
            });
        }
    }

2.FixedThreadPool

创建⼀个固定⼤⼩的线程池,可控制并发的线程数,超出的线程会在队列中等待.

例如:创建了一个有2个线程的线程池

 ExecutorService threadPool = Executors.newFixedThreadPool(2);

具体例子:

    public static void create02(){
        ExecutorService threadPool = Executors.newFixedThreadPool(2);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("当前线程名为:" + Thread.currentThread().getName());
            }
        };
        threadPool.submit(runnable);
        threadPool.execute(runnable);
        threadPool.submit(runnable);
        threadPool.execute(runnable);
    }

最后输出如下:可以看到有两种不同的线程,因为线程数被固定为了2,因此上面执行了四个任务,其每个线程都执行了2次。

该线程池有两个提交线程的方法,分别为submit和execute

submit可以执行有返回值的任务和无返回值的任务,而execute只能执行没有返回值的任务

3.CachedThreadPool

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

例子:

    public static void create03(){
        ExecutorService service = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            service.submit(() -> {
                System.out.println("当前线程名为:" + Thread.currentThread().getName());
            });
        }
    }

输出如下:创建了10个线程

4.ScheduledThread

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

例子:线程中的任务会在5s的延迟后执行

    public static void create04(){
        ScheduledExecutorService service = Executors.newScheduledThreadPool(5);
        System.out.println("任务开始前的时间:" + LocalDateTime.now());
        service.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("现在执行了任务:" + LocalDateTime.now());
            }
        },5, TimeUnit.SECONDS);
    }

5.SingleThreadExecutor

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

例子:

    public static void create05(){
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 4; i++) {
            final int index = i;
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("当前线程名为:" + Thread.currentThread().getName());
                }
            });
        }
    }

输出为:可以看到使用的都是一个线程

6.SingleThreadScheduledExecutor

同时具备上面两个线程池的特性,创建一个单线程的可以执行延迟任务的线程池。

    public static void create06(){
        ScheduledExecutorService threadPool = Executors.newSingleThreadScheduledExecutor();
        System.out.println("任务开始前的时间:" + LocalDateTime.now());
        threadPool.schedule(() -> {
            System.out.println("现在执行了任务:" + LocalDateTime.now());
        }, 2, TimeUnit.SECONDS);
    }

7.NewWorkStealingPool

创建一个抢占式执行的线程池(任务执行顺序不确定),此方法只有在 JDK 1.8以上的版本中才能使用。

例子:

    public static void create07(){
        ExecutorService threadPool = Executors.newWorkStealingPool();
        for (int i = 0; i < 5; i++) {
            threadPool.execute(() -> {
                System.out.println("线程名为:" + Thread.currentThread().getName());
            });
        }
        while (!threadPool.isTerminated()) {
        }
    }

  • 18
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值