ThreadPoolExecutor线程池问题,为啥没有实现Runnable接口,execute入参可以这样写?如下

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ThreadPoolExecutor线程池问题,为啥没有实现Runnable接口,execute入参可以这样写?如下相关的知识,希望对你有一定的参考价值。

public class Person
public static String getSddd()
System.out.println("dfdfdfdfffffffff");
return "dfddf";


public void hdg()
System.out.println("gggggggg");


public static void main(String[] args)
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
executor.execute(Person::getSddd);
executor.shutdown();


executor.execute(Person::getSddd);Person 这个类我都没有实现Runnable 接口,为什么可以这样写????

execute方法是ThreadPoolExecutor类中的一个方法,它需要一个Runnable对象作为其参数。Runnable只是一个具有可以被调用的run方法的对象。在Person类中的getSddd方法没有run方法,但是它正在使用方法引用作为参数传递给execute方法。
方法引用是创建调用现有方法的lambda表达式的简写方式,在这种情况下,即使Person类没有实现Runnable接口,也可以将getSddd方法的方法引用作为Runnable传递给execute方法。
当调用execute方法时,它会创建一个新线程,并在该线程中调用getSddd方法,从而使getSddd方法并发运行。
参考技术A 您可以使用 Java 8 的 Lambda 表达式实现接口的实例化,方法引用也可以作为 Lambda 表达式的一部分。在上面的示例中,Person::getSddd 方法就是一个 Lambda 表达式,它实现了 Runnable 接口,因此 Person 类无需实现 Runnable 接口也可以使用 executor 来执行该类中的方法。 参考技术B ThreadPoolExecutor线程池允许将任务传递给线程而无需实现Runnable接口,因此可以使用函数式编程语法(如lambda表达式和方法引用)来提交工作。在上面的示例中,Person::getSddd表示调用Person类中的静态方法getSddd,这个方法本质上就是Runnable接口的实现,因此可以直接被ThreadPoolExecutor线程池执行。

线程池ThreadPoolExecutor

一、线程池介绍

            在web开发中,服务器需要接受并处理请求,所以会为一个请求来分配一个线程来进行处理。如果每次请求都新创建一个线程的话实现起来非常简便,但是存在一个问题:

          如果并发的请求数量非常多,但每个线程执行的时间很短,这样就会频繁的创建和销毁线程,如此一来会大大降低系统的效率。可能出现服务器在为每个请求创建新线程和销毁线程上花费的时间和消耗的系统资源要比处理实际的用户请求的时间和资源更多。

          那么有没有一种办法使执行完一个任务,并不被销毁,而是可以继续执行其他的任务呢?

          这就是线程池的目的了。线程池为线程生命周期的开销和资源不足问题提供了解决方案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。

         什么时候使用线程池?

               单个任务处理时间比较短

               需要处理的任务数量很大

        使用线程池的好处

              降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。

              提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。

              提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

二、核心构造方法讲解

技术图片

 

参数说明: 

     corePoolSize:核心线程池大小

     maximumPoolSize:最大线程池大小

     keepAliveTime:线程池中超过corePoolSize数目的空闲线程最大存活时间

     unit:keepAliveTime的单位(纳秒、毫秒、秒、分、时等)

     workQueue:线程等待队列(阻塞任务队列)

                 可选值有:ArrayBlockingQueue: 有边界的阻塞队列。长度大小初始化时制定,即内部由数组实现

                                   LinkedBlockingQueue: 有边界的阻塞队列。边界是可选的,如果初始化的时候不指定则默认是Interger.MAX_VALUE,内部由链表实现。

                                   PriorityBlockQueue: 带有优先级的阻塞队列。没有边界。       

     threadFactory表示创建线程的工厂:可用默认的

     handler:拒绝策略(当提交任务数超过maxmumPoolSize+workQueue之和时,任务会交给RejectedExecutionHandler来处理)

                默认有四种方式:ThreadPoolExecutor.AbortPolicy:处理程序遭到拒绝将抛出运行时RejectedExecutionException。

                                          ThreadPoolExecutor.CallerRunsPolicy:调用线程直接call该任务的execute本身。

                                          ThreadPoolExecutor.DiscardPolicy:将任务删除。

                                          ThreadPoolExecutor.DiscardOldestPolicy删除工作队列头部任务。

               当然也可以自定义拒绝策略(定义一个类实现RejectedExecutionHandler接口,重写rejectedExecution方法即可)。

 

以上是关于ThreadPoolExecutor线程池问题,为啥没有实现Runnable接口,execute入参可以这样写?如下的主要内容,如果未能解决你的问题,请参考以下文章

解析ThreadPoolExecutor类是如何保证线程池正确运行的

线程池三个常用方法(底层实现ThreadPoolExecutor)

线程池类ThreadPoolExecutor介绍

线程池ThreadPoolExecutor

线程池ThreadPoolExecutor源码分析

ThreadPoolExecutor(线程池)源码分析