JavaEE 初阶篇-深入了解线程池(线程池创建、线程池如何处理任务)

🔥博客主页: 【小扳_-CSDN博客】
❤感谢大家点赞👍收藏⭐评论✍

文章目录

        1.0 线程池概述

        1.1 线程池的优点

        1.2 不使用线程池的问题

        1.3 线程池的工作原理图

        1.4 如何创建线程池? 

        2.0 通过 ThreadPoolExecutor 类自定义创建线程池

        2.1 ThreadPoolExecutor 构造器

        3.0 线程池处理 Runnable 任务

        3.1 通过 void execute(Runnable command) 方法

        3.2 通过 void shutdown() 方法

        3.3 通过 List shutdownNow() 方法

        3.4 临时线程什么时候创建?

        3.5 什么时候会开始拒绝新任务?

        4.0 线程池处理 Callable 任务

        4.1 通过 submit() 方法

        5.0 通过 Executors 工具类创建出线程池

        5.1 通过 Executors.newFixedThreadPool(int nThreads) 方法来创建线程池

        5.2 通过 Executors.newCachedThreadPool() 方法来创建线程池

        5.3 通过 Eexcutors.newSingleThreadExecutor() 方法来创建线程池

        6.0 新任务拒绝策略

        6.1 AbortPolicy(默认策略,直接抛出异常)

        6.2 DiscardPolicy(直接丢弃任务)

        6.3 CallerRunsPolicy(由调用线程执行任务)

        6.4 DiscardOldestPolicy(丢弃队列中最旧的任务)


        1.0 线程池概述

        线程池是一种重要的并发编程机制,用于管理和复用线程,以提高应用程序的性能和资源利用率。

        线程池就是一个可以复用线程的技术。

        1.1 线程池的优点

        1)降低线程创建和销毁的开销。通过重用线程从而减少频繁创建和开销线程所带来的性能损耗。

        2)控制并发线程数量。通过设定线程池的大小和配置,可以限制并发线程的数量,避免系统资源耗尽。

        1.2 不使用线程池的问题

        假设用户发起一个请求,后台就需要创建一个新线程来处理,下次新任务来了肯定又要创建新线程处理的,而创建新线程的开销是很大的,并且请求过多时,肯定会产生大量的线程出来,这样会严重影响系统的性能。

        1.3 线程池的工作原理图

        1.4 如何创建线程池? 

        常见的创建线程池的方式有两种:

        1)通过已经实现 ExecutorService 接口的 ThreadPoolExecutor 类来创建出线程池。

        2)通过 Executors 工具类创建出线程池。

 

        2.0 通过 ThreadPoolExecutor 类自定义创建线程池

        可以直接使用 ThreadPoolExecutor 类来创建自定义的线程池,通过指定核心线程数、最大线程数、工作队列等参数来满足特定的需求。这种方法更灵活,可以根据具体场景进行定制化配置。

        2.1 ThreadPoolExecutor 构造器

        1)参数一:corePoolSize:指定线程池的核心线程的数量。

        2)参数二:maximumPoolSize:指定线程池的最大线程数量。

        3)参数三:keepAliveTime:指定临时线程的存活时间。

        4)参数四:unit:指定临时线程的存活时间单位(秒、分、时、天)。

        5)参数五:workQueue:指定线程池的任务队列。

        6)参数六:threadFactory:指定线程池的线程工厂(创建线程的地方)。

        7)参数七:handler:指定线程池的任务拒绝策略(线程都在忙,任务队列也满的时候,新任务来了该怎么处理)。

具体创建线程池代码如下:

import java.util.concurrent.*;
public class CreateThreadPoolExecutor {public Executor threadPool = new ThreadPoolExecutor(3,//核心线程数量5,//最大线程数量8,//临时线程存活时间TimeUnit.SECONDS,//临时线程存活时间单位new ArrayBlockingQueue<>(4),//创建任务队列,最大存放任务数量为4Executors.defaultThreadFactory(),//线程工厂,//用到了Executors工具类来创建默认线程工厂new ThreadPoolExecutor.AbortPolicy());//拒绝策略,默认策略:抛出异常}

        

        3.0 线程池处理 Runnable 任务

        线程池通过执行 Runnable 任务来实现多线程处理。将实现 Runnable 接口的任务提交给线程池,线程池会根据配置的参数调度任务执行。核心线程数内的任务会立即执行,超出核心线程数的任务会被放入任务队列中。如果任务队列已满,且线程数未达到最大线程数,线程池会创建新线程执行任务。线程池管理线程的生命周期,重用线程以减少线程创建和销毁的开销。

ExecutorService 的常用方法:

        3.1 通过 void execute(Runnable command) 方法

        将 Runnable 类型的任务交给线程池,线程池就会自动创建线程,自动执行 run() 方法且自动启动线程。

代码如下:

import java.util.concurrent.*;
public class CreateThreadPoolExecutor {public static void main(String[] args) {Executor threadPool = new ThreadPoolExecutor(3,//核心线程数量5,//最大线程数量8,//临时线程存活时间TimeUnit.SECONDS,//临时线程存活时间单位new ArrayBlockingQueue<>(4),//创建任务队列,最大存放任务数量为4Executors.defaultThreadFactory(),//线程工厂,//用到了Executors工具类来创建默认线程工厂new ThreadPoolExecutor.AbortPolicy());//拒绝策略,默认策略:抛出异常//定义出Runnable类型的任务MyRunnable myRunnable1 = new MyRunnable();MyRunnable myRunnable2 = new MyRunnable();//将该任务提交给线程池threadPool.execute(myRunnable1);threadPool.execute(myRunnable2);}
}
class  MyRunnable implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "正在执行");}
}

运行结果:

        需要注意的是,任务执行完毕之后,线程池中的线程不会销毁,还在继续运行中

        3.2 通过 void shutdown() 方法

        等待全部任务执行完毕后,再关闭线程池。想要手动关闭线程池中的线程,可以用该方法,等待全部任务都执行后才会关闭。

代码如下:

import java.util.concurrent.*;
public class CreateThreadPoolExecutor {public static void main(String[] args) {Executor threadPool = new ThreadPoolExecutor(3,//核心线程数量5,//最大线程数量8,//临时线程存活时间TimeUnit.SECONDS,//临时线程存活时间单位new ArrayBlockingQueue<>(4),//创建任务队列,最大存放任务数量为4Executors.defaultThreadFactory(),//线程工厂,//用到了Executors工具类来创建默认线程工厂new ThreadPoolExecutor.AbortPolicy());//拒绝策略,默认策略抛出异常//定义出Runnable类型的任务MyRunnable myRunnable1 = new MyRunnable();MyRunnable myRunnable2 = new MyRunnable();//将该任务提交给线程池threadPool.execute(myRunnable1);threadPool.execute(myRunnable2);//当全部任务都执行结束后,才会关闭((ThreadPoolExecutor) threadPool).shutdown();}
}
class  MyRunnable implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "正在执行");}
}

运行结果:

        3.3 通过 List<Runnable> shutdownNow() 方法

        立刻关闭线程池,停止正在执行的任务,并返回队列中未执行的任务。先比较与以上的方法,当前的方法就很“激进”了。不管任务结束与否,都会关闭线程池中的线程。

代码如下:

import java.util.List;
import java.util.concurrent.*;
public class CreateThreadPoolExecutor {public static void main(String[] args) {Executor threadPool = new ThreadPoolExecutor(3,//核心线程数量5,//最大线程数量8,//临时线程存活时间TimeUnit.SECONDS,//临时线程存活时间单位new ArrayBlockingQueue<>(4),//创建任务队列,最大存放任务数量为4Executors.defaultThreadFactory(),//线程工厂,//用到了Executors工具类来创建默认线程工厂new ThreadPoolExecutor.AbortPolicy());//拒绝策略,默认策略:抛出异常//定义出Runnable类型的任务MyRunnable myRunnable1 = new MyRunnable();MyRunnable myRunnable2 = new MyRunnable();MyRunnable myRunnable3 = new MyRunnable();MyRunnable myRunnable4 = new MyRunnable();MyRunnable myRunnable5 = new MyRunnable();//将该任务提交给线程池threadPool.execute(myRunnable1);threadPool.execute(myRunnable2);threadPool.execute(myRunnable3);threadPool.execute(myRunnable4);threadPool.execute(myRunnable5);//还没执行完的任务会交给l链表List<Runnable> l = ((ThreadPoolExecutor) threadPool).shutdownNow();for (int i = 0; i < l.size(); i++) {System.out.println("还没来得及执行的任务:" + l.get(i));}}
}
class  MyRunnable implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "正在执行");}
}

运行结果:

        3.4 临时线程什么时候创建?

        新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以创建临时线程,此时才会创建临时线程。

代码如下:

import java.util.concurrent.*;
public class T {public static void main(String[] args) {Executor threadPool = new ThreadPoolExecutor(3,//核心线程数量5,//最大线程数量8,//临时线程存活时间TimeUnit.SECONDS,//临时线程存活时间单位new ArrayBlockingQueue<>(4),//创建任务队列,最大存放任务数量为4Executors.defaultThreadFactory(),//线程工厂,//用到了Executors工具类来创建默认线程工厂new ThreadPoolExecutor.AbortPolicy());//拒绝策略,默认策略抛出异常//定义出Runnable类型的任务,此时该三个任务都被核心线程正在处理MyRunnable myRunnable1 = new MyRunnable();MyRunnable myRunnable2 = new MyRunnable();MyRunnable myRunnable3 = new MyRunnable();//这里还没到临时线程创建的时机,被放入到任务队列中等待被核心线程执行MyRunnable myRunnable4 = new MyRunnable();MyRunnable myRunnable5 = new MyRunnable();MyRunnable myRunnable6 = new MyRunnable();MyRunnable myRunnable7 = new MyRunnable();//此时到了临时线程创建的时机了,核心线程都在满,队列已经满了//创建出第一个临时线程MyRunnable myRunnable8 = new MyRunnable();//创建出第二个临时线程MyRunnable myRunnable9 = new MyRunnable();//将该任务提交给线程池threadPool.execute(myRunnable1);threadPool.execute(myRunnable2);threadPool.execute(myRunnable3);threadPool.execute(myRunnable4);threadPool.execute(myRunnable5);threadPool.execute(myRunnable6);threadPool.execute(myRunnable7);threadPool.execute(myRunnable8);threadPool.execute(myRunnable9);}
}class  MyRunnable implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "==> 正在执行" + this);try {//在这里等待10sThread.sleep(10000);} catch (InterruptedException e) {throw new RuntimeException(e);}}
}

运行结果:

        当前的核心线程为 3 ,最大线程为 5 且任务队列有四个位置。当核心线程达到 3 时,且任务队列满 4 个了,还能创建临时线程时提交新任务就可以创建出临时线程了。

        3.5 什么时候会开始拒绝新任务?

        核心线程和临时线程都在忙,任务队列也满了,新的任务过来的时候才会开始拒绝任务。

代码如下:

import java.util.concurrent.*;
public class T {public static void main(String[] args) {Executor threadPool = new ThreadPoolExecutor(3,//核心线程数量5,//最大线程数量8,//临时线程存活时间TimeUnit.SECONDS,//临时线程存活时间单位new ArrayBlockingQueue<>(4),//创建任务队列,最大存放任务数量为4Executors.defaultThreadFactory(),//线程工厂,//用到了Executors工具类来创建默认线程工厂new ThreadPoolExecutor.AbortPolicy());//拒绝策略,默认策略抛出异常//定义出Runnable类型的任务,此时该三个任务都被核心线程正在处理MyRunnable myRunnable1 = new MyRunnable();MyRunnable myRunnable2 = new MyRunnable();MyRunnable myRunnable3 = new MyRunnable();//这里还没到临时线程创建的时机,被放入到任务队列中等待被核心线程执行MyRunnable myRunnable4 = new MyRunnable();MyRunnable myRunnable5 = new MyRunnable();MyRunnable myRunnable6 = new MyRunnable();MyRunnable myRunnable7 = new MyRunnable();//此时到了临时线程创建的时机了,核心线程都在满,队列已经满了//创建出第一个临时线程MyRunnable myRunnable8 = new MyRunnable();//创建出第二个临时线程MyRunnable myRunnable9 = new MyRunnable();//此时核心线程都在忙,且队列已经占满了,再提交新任务的时候,//就会采取拒绝策略MyRunnable myRunnable10 = new MyRunnable();//将该任务提交给线程池threadPool.execute(myRunnable1);threadPool.execute(myRunnable2);threadPool.execute(myRunnable3);threadPool.execute(myRunnable4);threadPool.execute(myRunnable5);threadPool.execute(myRunnable6);threadPool.execute(myRunnable7);threadPool.execute(myRunnable8);threadPool.execute(myRunnable9);threadPool.execute(myRunnable10);}
}class  MyRunnable implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "==> 正在执行" + this);try {//在这里等待10sThread.sleep(10000);} catch (InterruptedException e) {throw new RuntimeException(e);}}
}

运行结果:

        拒绝策略默认是抛出异常

        4.0 线程池处理 Callable 任务

        处理Callable任务时,线程池可通过 submit() 方法提交 Callable 实例,并返回代表任务执行情况的 Future 。通过 Future 可以获取任务执行结果或处理异常

ExecutorService 常见的方法:

        4.1 通过 submit() 方法

        提交 Callable 类型的任务给线程池,线程池会选择可用线程、自动执行 call() 方法、自动启动线程。

代码如下:

import java.util.concurrent.*;public class MyCreateThreadPool {public static void main(String[] args) throws ExecutionException, InterruptedException {ExecutorService executor = new ThreadPoolExecutor(3,5,8,TimeUnit.SECONDS,new ArrayBlockingQueue<>(4),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());//创建出Callable类型的实例对象MyCallable callable1 = new MyCallable(100);MyCallable callable2 = new MyCallable(200);MyCallable callable3 = new MyCallable(300);MyCallable callable4 = new MyCallable(400);//将任务提交到线程池中Future<String> f1 = executor.submit(callable1);Future<String> f2 = executor.submit(callable2);Future<String> f3 = executor.submit(callable3);Future<String> f4 = executor.submit(callable4);//拿到结果System.out.println(f1.get());System.out.println(f2.get());System.out.println(f3.get());System.out.println(f4.get());}
}

运行结果:

        5.0 通过 Executors 工具类创建出线程池

        Executors 工具类提供了创建不同类型线程池的方法,如 newFixedThreadPool 、 newCachedThreadPool、newSingleThreadExecutor 等。这些方法返回不同配置的线程池实例,可用于执行 Runnable 和 Callable 任务。通过 Executors 创建线程池,可方便地管理线程池的大小、任务队列、线程工厂等参数。注意合理选择线程池类型以满足任务需求,避免资源浪费或任务阻塞。

        简单来说,Executors 工具类为我们提供了不同特点的线程池。

        5.1 通过 Executors.newFixedThreadPool(int nThreads) 方法来创建线程池

        创建固定线程数量的线程池,如果某个线程因执行异常而结束,那么线程池会补充一个新线程代替它。

代码如下:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class demo1 {public static void main(String[] args) {//固定的线程池核心线程为3,临时线程为0,所以最大线程数量也就是3。ExecutorService pool = Executors.newFixedThreadPool(3);pool.execute(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "==> 正在执行");}});pool.execute(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "==> 正在执行");}});pool.execute(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "==> 正在执行");}});pool.execute(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "==> 正在执行");}});}
}

运行结果:

        其实 Executors.newFixedThreadPool(int nThreads) 方法的底层就是通过 ThreadPoolExecutor 类来实现创建线程池的。传入的参数就是核心线程线程数量,也为最大线程数量,因此临时线程数量为 0 。因此没有临时线程的存在,那么该线程池中的线程很固定

如图:

        5.2 通过 Executors.newCachedThreadPool() 方法来创建线程池

        线程数量随着任务增加而增加,如果线程任务执行完毕且空闲了 60 s则会被回收掉。也就是有多少了任务线程池会根据任务数量动态创建新线程。

代码如下:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;public class demo2 {public static void main(String[] args) {ExecutorService executorService = Executors.newCachedThreadPool();executorService.execute(() -> System.out.println(Thread.currentThread().getName() + " ==> 正在执行"));executorService.execute(() -> System.out.println(Thread.currentThread().getName() + " ==> 正在执行"));executorService.execute(() -> System.out.println(Thread.currentThread().getName() + " ==> 正在执行"));executorService.execute(() -> System.out.println(Thread.currentThread().getName() + " ==> 正在执行"));executorService.execute(() -> System.out.println(Thread.currentThread().getName() + " ==> 正在执行"));System.out.println( ((ThreadPoolExecutor)executorService).getPoolSize());}
}

        通过 getPoolSize() 方法可以拿到当前线程池中线程的数量。

运行结果如下:

        该方法创建出来的线程池特点为,当任务越多时候,线程池中的线程数量也会随之增加。其实这个方法的底层实现也是通过 ThreadPoolExecutor 类来实现创建线程池。

如图:

        很惊奇的发现,核心线程竟然是 0 个,而临时线程数量的最大值是非常非常大的,如果线程任务执行完毕且空闲了 60 s则会被回收掉。

        5.3 通过 Eexcutors.newSingleThreadExecutor() 方法来创建线程池

        创建只有一个线程的线程池对象,如果该线程出现异常而结束,那么线程池会补充一个新线程。

代码如下:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class demo3 {public static void main(String[] args) {ExecutorService executorService = Executors.newSingleThreadExecutor();executorService.execute(() -> System.out.println(Thread.currentThread().getName() + " ==> 正在执行"));executorService.execute(() -> System.out.println(Thread.currentThread().getName() + " ==> 正在执行"));executorService.execute(() -> System.out.println(Thread.currentThread().getName() + " ==> 正在执行"));executorService.execute(() -> System.out.println(Thread.currentThread().getName() + " ==> 正在执行"));executorService.execute(() -> System.out.println(Thread.currentThread().getName() + " ==> 正在执行"));executorService.execute(() -> System.out.println(Thread.currentThread().getName() + " ==> 正在执行"));}
}

运行结果:

        因为该线程池中只有一个线程,所以该线程需要执行所有的任务。因此该方法创建出来的线程池特点是,只有一个线程。当然该方法的底层也是通过 ThreadPoolExecutor 类来试下创建线程池。

如图:

        核心线程只有一个,最大线程也是一个,说明临时线程为零个。因此线程池中只有单一的线程。

        6.0 新任务拒绝策略

        常见的拒绝策略包括:AbortPolicy(默认策略,直接抛出异常)、CallerRunsPolicy(由调用线程执行任务)、DiscardPolicy(直接丢弃任务)、DiscardOldestPolicy(丢弃队列中最旧的任务)。

        6.1 AbortPolicy(默认策略,直接抛出异常)

        丢弃任务并抛出 RejectedExecutionExeception 异常,是默认的策略。

代码如下:

import java.util.concurrent.*;public class demo1 {public static void main(String[] args) {ExecutorService executorService = new ThreadPoolExecutor(2,3,8,TimeUnit.SECONDS,new ArrayBlockingQueue<>(2),Executors.defaultThreadFactory(),//默认拒绝新任务的策略new ThreadPoolExecutor.AbortPolicy());executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});//此时会有临时线程创建executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});//此时新任务提交的时候,会触发拒绝策略executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});}
}

运行结果:

        新提交的任务就被抛弃了且抛出异常。

        6.2 DiscardPolicy(直接丢弃任务)

        丢弃任务,但是不抛出异常,这是不推荐的做法。

代码如下:

import java.util.concurrent.*;public class demo1 {public static void main(String[] args) {ExecutorService executorService = new ThreadPoolExecutor(2,3,8,TimeUnit.SECONDS,new ArrayBlockingQueue<>(2),Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardPolicy());executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});//此时会有临时线程创建executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});//此时新任务提交的时候,会触发拒绝策略executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});}
}

运行结果:

        6.3 CallerRunsPolicy(由调用线程执行任务)

        由主线程负责调用任务的 run() 方法从而绕过线程池直接执行。

        简单来说,就是交给 main 主线程执行该任务。

代码如下:

import java.util.concurrent.*;public class demo1 {public static void main(String[] args) {ExecutorService executorService = new ThreadPoolExecutor(2,3,8,TimeUnit.SECONDS,new ArrayBlockingQueue<>(2),Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy());executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});//此时会有临时线程创建executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});//此时新任务提交的时候,会触发拒绝策略executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});}
}

        6.4 DiscardOldestPolicy(丢弃队列中最旧的任务)

        抛弃队列中等待最久的任务,然后把当前任务假如队列中。

import java.util.concurrent.*;public class demo1 {public static void main(String[] args) {ExecutorService executorService = new ThreadPoolExecutor(2,3,8,TimeUnit.SECONDS,new ArrayBlockingQueue<>(2),Executors.defaultThreadFactory(),//默认拒绝新任务的策略new ThreadPoolExecutor.DiscardOldestPolicy());executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});//此时会有临时线程创建executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});//此时新任务提交的时候,会触发拒绝策略executorService.execute(() -> {System.out.println(Thread.currentThread().getName() + "正在执行");try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {throw new RuntimeException(e);}});}
}

运行结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/300757.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于 Vue3 + Webpack5 + Element Plus Table 二次构建表格组件

基于 Vue3 Webpack5 Element Plus Table 二次构建表格组件 文章目录 基于 Vue3 Webpack5 Element Plus Table 二次构建表格组件一、组件特点二、安装三、快速启动四、单元格渲染配置说明五、源码下载地址 基于 Vue3 Webpack5 Element Plus Table 二次构建表格组件&#x…

有限的边界-DDD领域

从广义上讲&#xff0c;领域&#xff08;Domain&#xff09;即是一个组织所做的事情以及其中所包含的一切。商业机构通常会确定一个市场&#xff0c;然后在这个市场中销售产品和服务。每个组织都有它自己的业务范围和做事方式。这个业务范围以及在其中所进行的活动便是领域。当…

开源数据湖iceberg, hudi ,delta lake, paimon对比分析

Iceberg, Hudi, Delta Lake和Paimon都是用于大数据湖(Data Lake)或数据仓库(Data Warehouse)中数据管理和处理的工具或框架,但它们在设计、功能和适用场景上有所不同。 Iceberg: Iceberg是用于大型分析表的高性能格式。Iceberg将SQL表的可靠性和简易性带入到大数据领域,同…

【运输层】传输控制协议 TCP

目录 1、传输控制协议 TCP 概述 &#xff08;1&#xff09;TCP 的特点 &#xff08;2&#xff09;TCP 连接中的套接字概念 2、可靠传输的工作原理 &#xff08;1&#xff09;停止等待协议 &#xff08;2&#xff09;连续ARQ协议 3、TCP 报文段的首部格式 &#xff08;1…

Embedding:跨越离散与连续边界——离散数据的连续向量表示及其在深度学习与自然语言处理中的关键角色

Embedding嵌入技术是一种在深度学习、自然语言处理&#xff08;NLP&#xff09;、计算机视觉等领域广泛应用的技术&#xff0c;它主要用于将高维、复杂且离散的原始数据&#xff08;如文本中的词汇、图像中的像素等&#xff09;映射到一个低维、连续且稠密的向量空间中。这些低…

能否安全地删除 Mac 资源库中的文件?

在管理Mac电脑存储空间时&#xff0c;用户确实可能考虑对资源库&#xff08;Library&#xff09;文件夹进行清理以释放空间。Mac资源库是一个系统及应用程序存放重要支持文件的地方&#xff0c;其中包括但不限于配置文件、临时文件、缓存、插件、偏好设置、应用程序支持数据等。…

注意!今明两天广东等地仍有较强降雨

中央气象台监测显示 进入4月以来 我国江南、华南北部强降雨 接连而至 湖南、江西、浙江中南部 福建大部、广东中北部等地降雨量 较常年同期偏多1倍以上 上述地区部分国家观测站 日雨量突破4月历史极值 截至4月7日早晨 广东广州、惠州、清远 韶关、河源等地部分地区 …

利用Leaflet + React:构建WEBGIS

React是 Facebook 开发的一个开源库&#xff0c;用于构建用户界面。就其本身而言&#xff0c;Leaflet是一个用于将地图发布到网络的JavaScript 库。这两个工具的组合很简单&#xff0c;允许您创建动态网络地图。在本文中&#xff0c;我们将看到这种组合的一些特征以及一些简单的…

MTK i500p AIoT解决方案

一、方案概述 i500p是一款强大而高效的AIoT平台&#xff0c;专为便携式、家用或商用物联网应用而设计&#xff0c;这些应用通常需要大量的边缘计算&#xff0c;需要强大的多媒体功能和多任务操作系统。该平台集成了Arm Cortex-A73 和 Cortex-A53 的四核集群&#xff0c;工作频…

2024春算法训练4——函数与递归题解

一、前言 感觉这次的题目都很好&#xff0c;但是E题....&#xff08;我太菜了想不到&#xff09;&#xff0c;别人的题解都上百行了&#xff0c;晕&#xff1b; 二、题解 A-[NOIP2010]数字统计_2024春算法训练4——函数与递归 (nowcoder.com) 这种题目有两种做法&#xff1a;…

Flask Python Flask-SQLAlchemy中数据库的数据类型、flask中数据可的列约束配置

Flask Python Flask-SQLAlchemy中数据库的数据类型、flask中数据可的列约束配置 SQLAlchemy官方文档地址实战的代码分享数据类型列约束配置自定义方法 SQLAlchemy官方文档地址 SQLAlchemy官方文档地址 实战的代码分享 Flask-SQLAlchemy框架为创建数据库的实例提供了一个基类…

蓝桥杯—PCF8951

1.整个系统靠SDA和SCL实现完善的全双工数据传输 2.引脚图 AN1为光明电阻 AN3为滑动变阻 A0-A2均接地 时钟线连P20 地址线连P21 实物图 iic总线 谁控制时钟线谁是主设备 时序相关 官方提供的底层驱动代码 /* # I2C代码片段说明1. 本文件夹中提供的驱动代码供参赛选手完成…

Docker容器(五)Docker Compose

一、概述 1.1介绍 Docker Compose是Docker官方的开源项目&#xff0c;负责实现对Docker容器集群的快速编排。Compose 是 Docker 公司推出的一个工具软件&#xff0c;可以管理多个 Docker 容器组成一个应用。你需要定义一个 YAML 格式的配置文件docker-compose.yml&#xff0c;…

STC89C51学习笔记(五)

STC89C51学习笔记&#xff08;五&#xff09; 综述&#xff1a;文本讲述了代码中速写模板的创建、如何将矩阵键盘的按键与数字一一对应以及如何创建一个矩阵键盘密码锁。 一、速写模板 点击“templates”&#xff0c;再鼠标右键选择配置&#xff0c;按照以下方式即可修改一些…

4.7 IO day6

1&#xff1a;有一个隧道&#xff0c;全长5公里&#xff0c;有2列火车&#xff0c;全长200米&#xff0c; 火车A时速 100公里每小时 火车B时速 50公里每小时 现在要求模拟火车反复通过隧道的场景(不可能2列火车都在隧道内运行) #include <stdio.h> #include <string.…

Mac安装配置Appium

一、安装 nodejs 与 npm 安装方式与 windows 类似 &#xff0c;官网下载对应的 mac 版本的安装包&#xff0c;双击即可安装&#xff0c;无须配置环境变量。官方下载地址&#xff1a;https://nodejs.org/en/download/ 二、安装 appium Appium 分为两个版本&#xff0c;一个是…

【iOS】UITableView性能优化

文章目录 前言一、优化的本质二、卡顿产生原因三、CPU层面优化1.使用轻量级对象2.cellForRowAtIndexPath方法中不要做耗时操作3.UITableView的复用机制4.提前计算好布局了解tableView代理方法执行顺序cell高度计算rowHeightestimatedRowHeight 高度计算进行时机rowHeight计算时…

阿里云服务器可以干嘛?阿里云服务器八大用途介绍

阿里云服务器可以干嘛&#xff1f;能干啥你还不知道么&#xff01;简单来讲可用来搭建网站、个人博客、企业官网、论坛、电子商务、AI、LLM大语言模型、测试环境等&#xff0c;阿里云百科aliyunbaike.com整理阿里云服务器的用途&#xff1a; 阿里云服务器活动 aliyunbaike.com…

XML HTTP传输 小结

what’s XML XML 指可扩展标记语言&#xff08;eXtensible Markup Language&#xff09;。 XML 被设计用来传输和存储数据&#xff0c;不用于表现和展示数据&#xff0c;HTML 则用来表现数据。 XML 是独立于软件和硬件的信息传输工具。 应该掌握的基础知识 HTMLJavaScript…

视听杂志知网收录期刊投稿发表论文

《视听》是由国家新闻出版总署批准的正规的&#xff0c;兼有新闻传播、新媒体理论探索的当代学术性省级综合期刊。坚持正确的理论导向&#xff0c;全面展示广播影视事业发展中出现的新情况、新事物&#xff0c;探索现代传媒基础理论&#xff0c;研究网络传播、通讯传播等新媒体…