Java线程池讲义

合集下载

java线程池的使用例子

java线程池的使用例子

java线程池的使用例子随着计算机技术的不断发展,我们的软件系统越来越复杂,程序的性能要求也越来越高。

在这样的背景下,线程池成为了一种非常重要的工具。

Java线程池是Java提供的一种简单易用的线程管理工具,可以帮助我们更好地管理程序中的线程,提高程序的性能和稳定性。

本文将通过一个实际的例子来介绍Java线程池的使用方法和注意事项。

希望读者可以通过本文的学习,更好地掌握Java线程池的使用技巧。

一、什么是线程池?在介绍Java线程池之前,我们需要先了解什么是线程池。

线程池是一种管理线程的机制,可以帮助我们更好地管理程序中的线程,提高程序的性能和稳定性。

线程池的主要作用是为每个任务分配一个线程,当任务完成后,线程会被回收并可供下一个任务使用。

这样,线程的创建和销毁的开销就可以得到控制,避免了频繁创建和销毁线程所带来的性能损失。

二、Java线程池的使用方法1. 创建线程池Java线程池的创建方式非常简单,只需要使用ThreadPoolExecutor类即可。

以下是一个简单的线程池创建代码: ```ExecutorService executor =Executors.newFixedThreadPool(5);```这个代码创建了一个固定大小为5的线程池。

如果需要创建其他类型的线程池,可以使用其他的静态工厂方法,如newCachedThreadPool()、newSingleThreadExecutor()等。

2. 提交任务创建好线程池之后,我们就可以向线程池提交任务了。

以下是一个简单的线程池提交任务代码:```executor.submit(new Runnable() {@Overridepublic void run() {// 执行任务}});```这个代码提交了一个Runnable类型的任务,线程池会自动为其分配一个线程执行。

如果需要提交其他类型的任务,可以使用Callable、Future等接口。

Java框架中的线程池管理策略

Java框架中的线程池管理策略

Java框架中的线程池管理策略在Java框架中,线程池是一种常用的资源调度和管理机制,能够有效地管理和重用线程资源,提高应用程序的性能和并发处理能力。

本文将介绍Java框架中常用的线程池管理策略,并分析其适用场景和特点。

一、固定大小线程池(FixedThreadPool)固定大小线程池是一种最基础的线程池管理策略,它通过设定一个固定大小的线程池来管理线程资源。

在创建线程池时,会预先创建指定数量的线程,并将任务按顺序依次分配给这些线程进行执行。

当线程池中的线程被占满时,新的任务将会被暂存,等待有空闲线程可用时再执行。

固定大小线程池适用于负载相对稳定的场景,可以有效控制系统资源的使用。

二、缓存线程池(CachedThreadPool)缓存线程池是一种根据需要自动调整线程池大小的管理策略。

它会根据任务的数量自动调整线程池的大小,当任务增加时会自动扩大线程池,当任务减少时会自动缩小线程池。

这种策略适用于任务数波动较大的场景,能够更加灵活地管理线程资源,避免资源的浪费。

三、单线程线程池(SingleThreadExecutor)单线程线程池是一种只有一个线程的线程池管理策略。

它会按顺序执行每个任务,并保证所有任务都是按照添加的顺序执行的。

当某个任务执行失败时,会创建一个新线程来代替原来的线程继续执行后续任务。

单线程线程池适用于需要按顺序执行任务,并且任务间存在依赖关系的场景。

四、定时线程池(ScheduledThreadPool)定时线程池是一种可以定时执行任务的线程池管理策略。

它允许设置任务的执行时间和执行周期,可以在固定的时间间隔内周期性地执行任务。

定时线程池适用于需要按照一定的时间规律执行任务的场景,如定时任务调度、定期数据备份等。

五、工作窃取线程池(WorkStealingPool)工作窃取线程池是Java8新增的一种线程池管理策略。

它基于工作窃取算法,允许线程动态地从其他线程的任务队列中窃取任务执行,实现了任务的负载均衡。

java threadpoolexecutor用法 -回复

java threadpoolexecutor用法 -回复

java threadpoolexecutor用法-回复Java ThreadPoolExecutor是Java中用于管理线程池的一个类。

线程池可以提高多线程任务的执行效率,通过复用线程对象、控制并发线程数量和管理任务队列,能够更好地处理大量并发请求。

在本文中,我们将详细介绍ThreadPoolExecutor的用法和功能,以帮助开发者更好地使用它来处理多线程任务。

首先,我们需要了解ThreadPoolExecutor的基本概念和组成。

ThreadPoolExecutor是Executor框架的一个具体实现类,它利用一个线程池来执行指定的任务。

线程池由一组线程、任务队列和执行器组成。

线程池中的线程是预先创建的,它们可以被重复使用来执行多个任务。

任务队列用于存储待执行的任务,当线程池中的线程空闲时,它们会从任务队列中取出任务进行处理。

执行器用于控制任务的提交和执行。

接下来,我们将详细介绍ThreadPoolExecutor的构造函数和相关方法。

ThreadPoolExecutor的构造函数可以根据需要来创建一个线程池对象,它提供了多个参数来配置线程池的行为。

下面是ThreadPoolExecutor的构造函数和参数说明:javapublic ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)- corePoolSize:线程池的核心线程数量,即在没有任务需要执行时线程池中保留的线程数量。

- maximumPoolSize:线程池的最大线程数量,允许创建的最大线程数。

- keepAliveTime:当线程池中的线程数量大于核心线程数时,多余的空闲线程在终止之前等待新任务的最长时间。

javaspringboot线程池以及多线程

javaspringboot线程池以及多线程

javaspringboot线程池以及多线程线程和进程进程是资源分配的最⼩单位,线程是CPU调度的最⼩单位。

是不是很抽象,做个简单⽐喻,进程=⽕车,线程=车厢,线程在进程⾥运⾏(单个的车厢是⽆法运⾏的);不同进程之间数据很难共享,同⼀进程下的线程数据共享则很容易。

多线程⼀个应⽤程序有多条执⾏路径(单线程:⼀个应⽤程序只有⼀条执⾏路径)。

应⽤场景异步,有些功能⽆需同步执⾏,可以使⽤另外⼀个线程去执⾏。

多个线程共同完成⼀个事情,缩短整体执⾏时间,同时cpu也得到了充分利⽤(例如,盖房⼦垒墙,⼀个⼈需要10天,10个⼈同时做,1天左右可以完成)。

线程池什么是线程池线程池,顾名思义,是存放了⼀堆线程的池⼦/容器,并且管理线程的整个⽣命周期。

java.util.concurrent.Executors提供了⼀个 java.util.concurrent.Executor接⼝的实现⽤于创建线程池。

为什么要⽤线程池1. 减少了创建和销毁线程的次数,每个⼯作线程都可以被重复利⽤,可执⾏多个任务。

2. 可以根据系统的承受能⼒,调整线程池中⼯作线线程的数⽬,防⽌因为消耗过多的内存,⽽把服务器累趴下(每个线程需要⼤约1MB内存,线程开的越多,消耗的内存也就越⼤,最后死机)。

实现⽅式此处以springboot实现⽅式为例import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.EnableAsync;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.Executor;import java.util.concurrent.ThreadPoolExecutor;/*** @author lipeiguang*/@Configuration@EnableAsyncpublic class ThreadPoolConfig {@Bean(name = "executor")public Executor getAsyncThread() {ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();//线程池维护线程的最少数量taskExecutor.setCorePoolSize(5);//线程池维护线程的最⼤数量,只有在缓冲队列满了之后才会申请超过核⼼线程数的线程taskExecutor.setMaxPoolSize(10);//缓存队列taskExecutor.setQueueCapacity(20);//允许的空闲时间,当超过了核⼼线程出之外的线程在空闲时间到达之后会被销毁taskExecutor.setKeepAliveSeconds(200);//线程名称前缀taskExecutor.setThreadNamePrefix("my-thread-");// 线程池对拒绝任务(⽆线程可⽤)的处理策略,⽬前只⽀持AbortPolicy、CallerRunsPolicy;默认为后者taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());// 调度器shutdown被调⽤时等待当前被调度的任务完成taskExecutor.setWaitForTasksToCompleteOnShutdown(true);// 等待时长taskExecutor.setAwaitTerminationSeconds(60);taskExecutor.initialize();return taskExecutor;}}其中的corePoolSize设置参考:N为cpu个数如果是CPU密集型应⽤,则线程池⼤⼩设置为N+1如果是IO密集型应⽤,则线程池⼤⼩设置为2N+1cpu个数查询⽅式:Runtime.getRuntime().availableProcessors();linux查询⽅式:cat /proc/cpuinfo| grep"processor"| wc -l使⽤线程池实现异步import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;import java.util.concurrent.Executor;/*** 使⽤demo* @author lipeiguang*/@Slf4j@Api(tags = {"异步线程测试"})@RestControllerpublic class ExecutorDemo {//使⽤时通过注解/*** 如果是多线程,可以直接使⽤这个executor*/@Resource(name = TaskExecutorConstant.SALARY_TASK_EXECUTOR) private Executor executor;@Autowiredprivate ServiceDemo serviceDemo;@ApiOperation("异步测试")@GetMapping("/test/async")public String testAsync(){("主线程开始执⾏。

java定时器线程池(ScheduledThreadPoolExecutor)的实现

java定时器线程池(ScheduledThreadPoolExecutor)的实现

java定时器线程池(ScheduledThreadPoolExecutor)的实现前⾔定时器线程池提供了定时执⾏任务的能⼒,即可以延迟执⾏,可以周期性执⾏。

但定时器线程池也还是线程池,最底层实现还是ThreadPoolExecutor,可以参考我的另外⼀篇⽂章多线程–精通ThreadPoolExecutor。

特点说明1.构造函数public ScheduledThreadPoolExecutor(int corePoolSize) {// 对于其他⼏个参数在ThreadPoolExecutor中都已经详细分析过了,所以这⾥,将不再展开// 这⾥我们可以看到调⽤基类中的⽅法时有个特殊的⼊参DelayedWorkQueue。

// 同时我们也可以发现这⾥并没有设置延迟时间、周期等参数⼊⼝。

// 所以定时执⾏的实现必然在DelayedWorkQueue这个对象中了。

super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,new DelayedWorkQueue());}2.DelayedWorkQueueDelayedWorkQueue是在ScheduledThreadPoolExecutor的⼀个内部类,实现了BlockingQueue接⼝⾥⾯存放任务队列的数组如下:private RunnableScheduledFuture<?>[] queue =new RunnableScheduledFuture<?>[INITIAL_CAPACITY];我们分析过ThreadPoolExecutor,它从任务队列中获取任务的⽅式为poll和take两种,所以看⼀下poll和take两个⽅法的源码,回顾⼀下,ThreadPoolExecutor它会调⽤poll或take⽅法,先poll,再take,只要其中⼀个接⼝有返回就⾏public RunnableScheduledFuture<?> poll() {final ReentrantLock lock = this.lock;lock.lock();try {RunnableScheduledFuture<?> first = queue[0];// 这⾥有个getDelay,这是关键点,获取执⾏延时时间// 但是如果我们有延时设置的话,这就返回空了,然后就会调⽤take⽅法if (first == null || first.getDelay(NANOSECONDS) > 0)return null;elsereturn finishPoll(first);} finally {lock.unlock();}}public RunnableScheduledFuture<?> take() throws InterruptedException {final ReentrantLock lock = this.lock;lock.lockInterruptibly();try {for (;;) {RunnableScheduledFuture<?> first = queue[0];if (first == null)available.await();else {// 获取延时时间long delay = first.getDelay(NANOSECONDS);if (delay <= 0)return finishPoll(first);first = null; // don't retain ref while waitingif (leader != null)available.await();else {Thread thisThread = Thread.currentThread();leader = thisThread;try {// 使⽤锁,执⾏延时等待。

JAVA自定义线程池的最大线程数设置方法

JAVA自定义线程池的最大线程数设置方法

JAVA自定义线程池的最大线程数设置方法一、Java自定义线程池的作用线程池是一个减少在应用程序中创建和销毁线程的机制,它可以对线程进行重用,使线程池可以解决多线程同步的问题,提高程序服务能力,减少资源消耗,提高程序效率。

二、Java自定义线程池的原理创建线程池时,它会先创建固定数量的线程(拒绝政策),并将它们放入空闲队列中,当有任务需要处理时,会从队列中取出一个空闲线程来处理,有可能是一个新线程也可能是一个已存在的线程,比如,如果空闲队列中还有可用的线程,就会重新使用这些线程,而不会重新创建新的线程;如果空闲队列为空,则会创建新的线程来处理任务。

当一个线程处理完任务后,它会被重新放入空闲队列等待下一次处理任务。

如果空闲队列中线程数量超过了最大线程数,则这些空闲线程会被终止。

三、自定义线程池的最大线程数设置1.通过ThreadPoolExecutor.Builder类中的maximumPoolSize方法来设置最大线程数ThreadPoolExecutor.Builder builder = new ThreadPoolExecutor.Builder(;builder.maximumPoolSize(maxThreads);2.通过ThreadPoolExecutor类中的setMaximumPoolSize方法来设置最大线程数ThreadPoolExecutor executor = new ThreadPoolExecutor(; executor.setMaximumPoolSize(maxThreads);3.通过Executors类下的有参方法来设置最大线程数Executors.newFixedThreadPool(maxThreads);4.通过自定义ThreadPoolExecutor类来设置最大线程数public class MyThreadPoolExecutor extends ThreadPoolExecutor private int maxThreads;。

java threadpoolexecutor 参数

java threadpoolexecutor 参数

java threadpoolexecutor 参数【原创实用版】目录1.Java 线程池概述2.ThreadPoolExecutor 参数介绍3.ThreadPoolExecutor 参数的具体用法和配置4.ThreadPoolExecutor 参数对线程池性能的影响5.总结正文一、Java 线程池概述Java 线程池(ThreadPoolExecutor)是 Java 并发编程中常用的一种线程管理工具,它能够有效地重用线程,减少线程的创建和销毁的开销,提高程序的执行效率。

线程池可以分为固定线程数量的线程池和可调整线程数量的线程池,其中可调整线程数量的线程池又分为两种:一种是线程数量固定的线程池,另一种是线程数量动态调整的线程池。

二、ThreadPoolExecutor 参数介绍ThreadPoolExecutor 是 Java 线程池的实现类,它提供了一系列的参数来配置线程池,这些参数主要包括:1.核心线程数(corePoolSize):线程池中的核心线程数量,即线程池中最少需要保持的线程数量。

当线程池中的线程数量小于corePoolSize 时,线程池会自动创建新的线程。

2.最大线程数(maxPoolSize):线程池中的最大线程数量。

当线程池中的线程数量达到 maxPoolSize 时,线程池将不再创建新的线程。

3.队列容量(queueCapacity):线程池中的任务队列容量。

当线程池中的线程数量达到 maxPoolSize,且任务队列已满时,线程池将拒绝新的任务。

4.拒绝策略(rejectedExecutionHandler):当线程池无法执行新任务时,可以采用的拒绝策略。

常用的拒绝策略有:AbortPolicy(默认策略,直接抛出异常)、CallerRunsPolicy(让调用者执行任务)、DiscardPolicy(直接丢弃任务,不抛出异常)和 DiscardOldestPolicy (丢弃队列中最旧的任务,然后尝试执行新任务)。

6、java5线程池之固定大小线程池newFixedThreadPool

6、java5线程池之固定大小线程池newFixedThreadPool

6、java5线程池之固定⼤⼩线程池newFixedThreadPoolJDK⽂档说明:创建⼀个可重⽤固定线程数的线程池,以共享的⽆界队列⽅式来运⾏这些线程。

在任意点,在⼤多数 nThreads 线程会处于处理任务的活动状态。

如果在所有线程处于活动状态时提交附加任务,则在有可⽤线程之前,附加任务将在队列中等待。

如果创建⽅法:java.util.concurrent.Executors.newFixedThreadPool(int nThreads)orjava.util.concurrent.Executors.newFixedThreadPool(int nThreads, ThreadFactory threadFactory)调⽤上⾯2个⽅法得到的对象为:ExecutorServiceJDK⾃带的例⼦:下⾯给出了⼀个⽹络服务的简单结构,这⾥线程池中的线程作为传⼊的请求。

它使⽤了预先配置的Executors.newFixedThreadPool(int)⼯⼚⽅法:class NetworkService implements Runnable {private final ServerSocket serverSocket;private final ExecutorService pool;public NetworkService(int port, int poolSize) throws IOException {serverSocket = new ServerSocket(port);pool = Executors.newFixedThreadPool(poolSize);}public void run() { // run the servicetry {for (;;) {pool.execute(new Handler(serverSocket.accept()));}} catch (IOException ex) {pool.shutdown();}}}class Handler implements Runnable {private final Socket socket;Handler(Socket socket) { this.socket = socket; }public void run() {// read and service request on socket}}主要的⽅法:boolean awaitTermination(long timeout, TimeUnit unit)请求关闭、发⽣超时或者当前线程中断,⽆论哪⼀个⾸先发⽣之后,都将导致阻塞,直到所有任务完成执⾏。

Java线程池使用和常用参数

Java线程池使用和常用参数

Java线程池使⽤和常⽤参数多线程问题:1、java中为什么要使⽤多线程使⽤多线程,可以把⼀些⼤任务分解成多个⼩任务来执⾏,多个⼩任务之间互不影像,同时进⾏,这样,充分利⽤了cpu资源。

2、java中简单的实现多线程的⽅式继承Thread类,重写run⽅法;12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28class MyTread extends Thread{public void run() { System.out.println(Thread.currentThread().getName());}}实现Runable接⼝,实现run⽅法;class MyRunnable implements Runnable{ public void run() { System.out.println(Thread.currentThread().getName()); }}class ThreadTest { public static void main(String[] args) { MyTread thread = new Mythread(); thread.start(); //开启⼀个线程 MyRunnable myRunnable = new MyRunnable(); Thread runnable = new Thread(myRunnable); runnable.start(); //开启⼀个线程 }}3、java线程的状态创建:当new了⼀个线程,并没有调⽤start之前,线程处于创建状态;就绪:当调⽤了start之后,线程处于就绪状态,这是,线程调度程序还没有设置执⾏当前线程;运⾏:线程调度程序执⾏到线程时,当前线程从就绪状态转成运⾏状态,开始执⾏run⽅法⾥边的代码;阻塞:线程在运⾏的时候,被暂停执⾏(通常等待某项资源就绪后在执⾏,sleep、wait可以导致线程阻塞),这是该线程处于阻塞状态;死亡:当⼀个线程执⾏完run⽅法⾥边的代码或调⽤了stop⽅法后,该线程结束运⾏4、为什么要引⼊线程池当我们需要的并发执⾏线程数量很多时,且每个线程执⾏很短的时间就结束了,这样,我们频繁的创建、销毁线程就⼤⼤降低了⼯作效率(创建和销毁线程需要时间、资源)。

newscheduledthreadpool corepolesize

newscheduledthreadpool corepolesize

newscheduledthreadpool corepolesize本文将围绕Java中的线程池常用参数“newScheduledThreadPool corePoolSize”进行阐述。

线程池是一种常见的多线程编程技术,通过重用已有线程来减少创建新线程的开销,从而提高程序执行效率。

具体将从以下几个方面进行讲解:1. 线程池简介2. newScheduledThreadPool的作用及使用3. corePoolSize参数的理解4. 实例演示一、线程池简介线程池是Java多线程编程中常用的一种技术,Java语言提供了3种线程池:FixedThreadPool、CachedThreadPool和ScheduledThreadPool。

线程池中包含若干个线程,用于执行多个任务。

当有任务到达时,线程池会从线程池中选取一个可用线程执行任务,如果没有可用线程,则等待直到有空闲线程。

线程池的好处在于可以重复利用线程,减少线程创建和销毁的开销,提高程序性能,同时避免了线程数量过多导致程序崩溃的问题。

二、newScheduledThreadPool的作用及使用newScheduledThreadPool是Java提供的一种ScheduledThreadPoolExecutor类型的线程池。

ScheduledThreadPoolExecutor是一个大小可调的线程池,可以延迟或定时执行任务。

newScheduledThreadPool可以根据需要创建新线程,并通过参数进行控制线程池的大小和时间。

使用newScheduledThreadPool可以更好地控制和执行一些需要定时触发的任务。

3. corePoolSize参数的理解newScheduledThreadPool中的corePoolSize参数是控制线程池中的核心线程数量的参数。

核心线程是指在线程池中一直存在的线程,在线程池有足够任务需要执行时,核心线程会一直存在。

浅谈Java线程池的7大核心参数

浅谈Java线程池的7大核心参数

浅谈Java线程池的7⼤核⼼参数⽬录前⾔⼀、线程池的创建及重要参数⼆、ThreadPoolExecutor中重要的⼏个参数详解三、workQueue队列(阻塞队列)四、常见的⼏种⾃动创建线程池⽅式五、线程池实现线程复⽤的原理六、⼿动创建线程池(推荐)七、Springboot中使⽤线程池前⾔java中经常需要⽤到多线程来处理⼀些业务,我不建议单纯使⽤继承Thread或者实现Runnable接⼝的⽅式来创建线程,那样势必有创建及销毁线程耗费资源、线程上下⽂切换问题。

同时创建过多的线程也可能引发资源耗尽的风险,这个时候引⼊线程池⽐较合理,⽅便线程任务的管理。

java中涉及到线程池的相关类均在jdk1.5开始的java.util.concurrent包中,涉及到的⼏个核⼼类及接⼝包括:Executor、Executors、ExecutorService、ThreadPoolExecutor、FutureTask、Callable、Runnable等。

⼀、线程池的创建及重要参数线程池可以⾃动创建也可以⼿动创建,⾃动创建体现在Executors⼯具类中,常见的可以创建newFixedThreadPool、newCachedThreadPool、newSingleThreadExecutor、newScheduledThreadPool;⼿动创建体现在可以灵活设置线程池的各个参数,体现在代码中即ThreadPoolExecutor类构造器上各个实参的不同:public static ExecutorService newFixedThreadPool(int var0) {return new ThreadPoolExecutor(var0, var0, 0L, LISECONDS, new LinkedBlockingQueue());}public static ExecutorService newSingleThreadExecutor() {return new Executors.FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, LISECONDS, new LinkedBlockingQueue()));}public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, 2147483647, 60L, TimeUnit.SECONDS, new SynchronousQueue());}public static ScheduledExecutorService newScheduledThreadPool(int var0) {return new ScheduledThreadPoolExecutor(var0);}(重点)public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) {……}⼆、ThreadPoolExecutor中重要的⼏个参数详解corePoolSize:核⼼线程数,也是线程池中常驻的线程数,线程池初始化时默认是没有线程的,当任务来临时才开始创建线程去执⾏任务maximumPoolSize:最⼤线程数,在核⼼线程数的基础上可能会额外增加⼀些⾮核⼼线程,需要注意的是只有当workQueue队列填满时才会创建多于corePoolSize 的线程(线程池总线程数不超过maxPoolSize)keepAliveTime:⾮核⼼线程的空闲时间超过keepAliveTime就会被⾃动终⽌回收掉,注意当corePoolSize=maxPoolSize时,keepAliveTime参数也就不起作⽤了(因为不存在⾮核⼼线程);unit:keepAliveTime的时间单位workQueue:⽤于保存任务的队列,可以为⽆界、有界、同步移交三种队列类型之⼀,当池⼦⾥的⼯作线程数⼤于corePoolSize时,这时新进来的任务会被放到队列中threadFactory:创建线程的⼯⼚类,默认使⽤Executors.defaultThreadFactory(),也可以使⽤guava库的ThreadFactoryBuilder来创建handler:线程池⽆法继续接收任务(队列已满且线程数达到maximunPoolSize)时的饱和策略,取值有AbortPolicy、CallerRunsPolicy、DiscardOldestPolicy、DiscardPolicy线程池中的线程创建流程图:(基于<Java并发编程的艺术>⼀书)举个例⼦:现有⼀个线程池,corePoolSize=10,maxPoolSize=20,队列长度为100,那么当任务过来会先创建10个核⼼线程数,接下来进来的任务会进⼊到队列中直到队列满了,会创建额外的线程来执⾏任务(最多20个线程),这个时候如果再来任务就会执⾏拒绝策略。

JAVA面试题之七—线程池的工作原理和7个参数

JAVA面试题之七—线程池的工作原理和7个参数

JAVA⾯试题之七—线程池的⼯作原理和7个参数线程池的⼯作原理和7个参数(京东物流、美团充电宝⼀⾯、中信银⾏⼀⾯、美团外卖⼀⾯、58⽤户平台⼀⾯、轻松集团)7个参数corePoolSize:线程池核⼼线程数量maximumPoolSize:线程池最⼤线程数量keepAliverTime:当活跃线程数⼤于核⼼线程数时,空闲的多余线程最⼤存活时间unit:存活时间的单位workQueue:存放任务的队列threadFactory:创建线程的⼯⼚handler:超出线程范围和队列容量的任务的处理程序每个值为什么这么设置?⼯作原理例⼦:核⼼线程数量为5个;全部线程数量为10个;⼯作队列的长度为5。

刚开始都是在创建新的线程,达到核⼼线程数量5个后,新的任务进来后不再创建新的线程,⽽是将任务加⼊⼯作队列;任务队列到达上线5个后,新的任务⼜会创建新的普通线程,直到达到线程池最⼤的线程数量10个;后⾯的任务则根据配置的饱和策略来处理。

我们这⾥没有具体配置,使⽤的是默认的配置AbortPolicy:直接抛出异常。

当当前任务⼩于最⼤线程数的时候,线程资源会保持核⼼线程池个数的线程,其他超过的线程资源在存活时间时间之后会被回收。

拒绝策略1、AbortPolicy:直接抛出异常2、CallerRunsPolicy:只⽤调⽤所在的线程运⾏任务3、DiscardOldestPolicy:丢弃队列⾥最近的⼀个任务,并执⾏当前任务。

4、DiscardPolicy:不处理,丢弃掉。

代码import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.RejectedExecutionHandler;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;/*** 线程池测试* 使⽤丢弃策略处理多余线程,不管多余线程*/public class ThreadPoolTest2 {public static void main(String[] args) {LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(5);// 丢弃策略,多余的线程直接不处理,丢弃RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();// 创建线程池 5 10 60sThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 10, 60,TimeUnit.SECONDS, queue, handler);for (int i = 1; i <= 16; i++) {threadPool.execute(new Thread(new ThreadTest(), "Thread".concat(i + "")));System.out.println("线程池中活跃的线程数: " + threadPool.getPoolSize());if (queue.size() > 0) {System.out.println("-------队列中阻塞的线程数" + queue.size());}}threadPool.shutdown();}}输出:com.geniu.concurrent.ThreadPool.ThreadPoolTest2线程池中活跃的线程数: 1线程池中活跃的线程数: 2线程池中活跃的线程数: 3线程池中活跃的线程数: 4线程池中活跃的线程数: 5线程池中活跃的线程数: 5 -------队列中阻塞的线程数1线程池中活跃的线程数: 5 -------队列中阻塞的线程数2线程池中活跃的线程数: 5 -------队列中阻塞的线程数3线程池中活跃的线程数: 5 -------队列中阻塞的线程数4线程池中活跃的线程数: 5 -------队列中阻塞的线程数5线程池中活跃的线程数: 6 -------队列中阻塞的线程数5线程池中活跃的线程数: 7 -------队列中阻塞的线程数5线程池中活跃的线程数: 8 -------队列中阻塞的线程数5线程池中活跃的线程数: 9 -------队列中阻塞的线程数5线程池中活跃的线程数: 10 -------队列中阻塞的线程数5线程池中活跃的线程数: 10 -------队列中阻塞的线程数5。

java线程池的工作原理

java线程池的工作原理

java线程池的工作原理
Java线程池的工作原理如下:
1. 线程池的初始化:在使用线程池之前,需要首先创建一个线程池对象,并设定线程池的核心线程数、最大线程数、线程空闲时间等参数。

2. 任务提交:当有任务需要执行时,可以使用线程池的
submit()或execute()方法将任务提交给线程池。

3. 任务队列:线程池会维护一个任务队列,用于存储提交的任务。

如果线程池中的线程数没有达到核心线程数,线程池就会创建新的线程来执行任务。

如果线程池中的线程数已经达到核心线程数,但任务队列仍然可以存储新任务,线程池会将新任务存储在任务队列中。

4. 线程池的工作方式:线程池会不断地从任务队列中取出任务,并通过线程池中的线程来执行任务。

若线程池中的线程处于空闲状态,则会被重新利用,否则任务会等待直到有线程可用。

5. 线程池的扩容:当任务队列已满且线程池中的线程数未达到最大线程数时,线程池会创建新的线程来执行任务。

一旦线程数达到最大线程数,线程池将不再接受新的任务。

6. 线程池的关闭:当不再需要线程池时,可以调用线程池的shutdown()方法来关闭线程池。

关闭线程池后,线程池将不再
接受新的任务,同时会等待已提交的任务执行完毕。

可以使用
awaitTermination()方法来等待所有任务执行完毕。

线程池的好处是提高了线程的利用率,避免了频繁创建和销毁线程的开销。

同时可以控制线程的并发数,防止系统资源过度消耗。

javascheduledthreadpool原理

javascheduledthreadpool原理

javascheduledthreadpool原理ScheduledThreadPool 是 Java 中的一个线程池,它可以用于在指定的时间和指定的间隔执行任务。

其原理如下:ScheduledThreadPool 是 ThreadPoolExecutor 的子类,它使用一个DelayedWorkQueue 作为任务队列来存储任务。

DelayedWorkQueue 是一个按照任务的延迟时间进行排序的队列。

其中,延迟时间是任务的执行时间减去当前时间。

ScheduledThreadPool 内部维护一个线程池,可以根据需要动态创建或销毁线程。

ScheduledThreadPool 的核心组件有:1. 线程池(ThreadPoolExecutor):用于执行任务的线程池,根据任务的数量和执行的频率动态创建或销毁线程。

2. 任务队列(DelayedWorkQueue):用于存储任务的队列,按照任务的延迟时间进行排序。

3. 定时器(ScheduledFutureTask):用于延迟和周期性执行任务的定时器,负责创建和调度任务。

当向 ScheduledThreadPool 提交一个任务时,线程池会先判断队列中是否有已经过期的任务。

如果有,线程池会从队列中取出任务并且立即执行。

否则,线程池会根据任务的延迟时间,计算出任务的执行时间,并将任务放入队列中。

然后,线程池会根据需要创建线程或者激活空闲线程来执行任务。

每个线程在执行任务时会先从队列中取出延迟时间已过的任务,然后执行任务的 run 方法。

在任务执行完成后,ScheduledThreadPool 会根据任务的执行结果和周期性设置决定是否需要重新放入队列。

如果任务执行结果为周期性执行并且周期时间大于 0,则将任务的执行时间设置为当前时间加上周期时间,并将任务重新放入队列中。

否则,任务被认为是一次性任务,不会重新放入队列。

ScheduledThreadPool 的原理可以概括为以下几个步骤:1.创建线程池和任务队列,以及定时器。

Java多线程编程技巧详解

Java多线程编程技巧详解

Java多线程编程技巧详解Java是一种广泛使用的编程语言,而多线程编程则是Java中一个重要的开发领域。

在多线程编程中,开发者需要了解并掌握一定的技巧,以避免线程之间的冲突和死锁等问题。

本文将详细介绍Java多线程编程的常用技巧,帮助开发者轻松掌握多线程编程的精髓。

一、线程的创建与启动1. 继承Thread类创建线程:直接继承Thread类,并覆盖run()方法实现线程主体。

```public class MyThread extends Thread{public void run(){//线程执行体}}MyThread myThread = new MyThread();myThread.start();```2. 实现Runnable接口创建线程:实现Runnable接口,并在类中实例化一个Thread对象。

```public class MyRunnable implements Runnable{public void run(){//线程执行体}}MyRunnable myRunnable = new MyRunnable();Thread thread = new Thread(myRunnable);thread.start();```二、线程的处理与管理1. 同步方法:synchronized关键字用于保护共享数据不被多个线程同时访问。

```public class SynchronizedDemo implements Runnable {private int count;public synchronized void run() {for(int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName()+":"+(count++));}}}SynchronizedDemo target = new SynchronizedDemo();Thread thread1 = new Thread(target, "A");Thread thread2 = new Thread(target, "B");thread1.start();thread2.start();```2. 锁对象:使用互斥锁对象来控制线程访问共享资源的方式。

ThreadPoolExecutor中策略的选择与工作队列的选择(java线程池)

ThreadPoolExecutor中策略的选择与工作队列的选择(java线程池)

ThreadPoolExecutor中策略的选择与⼯作队列的选择(java线程池)⼯作原理1、线程池刚创建时,⾥⾯没有⼀个线程。

任务队列是作为参数传进来的。

不过,就算队列⾥⾯有任务,线程池也不会马上执⾏它们。

2、当调⽤ execute() ⽅法添加⼀个任务时,线程池会做如下判断:a. 如果正在运⾏的线程数量⼩于 corePoolSize,那么马上创建线程运⾏这个任务; b. 如果正在运⾏的线程数量⼤于或等于 corePoolSize,那么将这个任务放⼊队列。

c. 如果这时候队列满了,⽽且正在运⾏的线程数量⼩于 maximumPoolSize,那么还是要创建线程运⾏这个任务; d. 如果队列满了,⽽且正在运⾏的线程数量⼤于或等于 maximumPoolSize,那么线程池会抛出异常,告诉调⽤者“我不能再接受任务了”。

3、当⼀个线程完成任务时,它会从队列中取下⼀个任务来执⾏。

4、当⼀个线程⽆事可做,超过⼀定的时间(keepAliveTime)时,线程池会判断,如果当前运⾏的线程数⼤于 corePoolSize,那么这个线程就被停掉。

所以线程池的所有任务完成后,它最终会收缩到 corePoolSize 的⼤⼩。

这样的过程说明,并不是先加⼊任务就⼀定会先执⾏。

假设队列⼤⼩为 10,corePoolSize 为 3,maximumPoolSize 为 6,那么当加⼊20 个任务时,执⾏的顺序就是这样的:⾸先执⾏任务 1、2、3,然后任务 4~13 被放⼊队列。

这时候队列满了,任务 14、15、16 会被马上执⾏,⽽任务 17~20 则会抛出异常。

最终顺序是:1、2、3、14、15、16、4、5、6、7、8、9、10、11、12、13。

下⾯是⼀个线程池使⽤的例⼦:排队所有都可⽤于传输和保持提交的任务。

可以使⽤此队列与池⼤⼩进⾏交互:如果运⾏的线程少于 corePoolSize,则 Executor 始终⾸选添加新的线程,⽽不进⾏排队。

java 线程池 参数

java 线程池 参数

java 线程池参数在Java 中,线程池是一种用于管理和重用线程的机制,它可以在执行大量任务时提供更好的性能和资源管理。

Java 提供了`java.util.concurrent` 包,其中包括`Executor` 框架,用于创建和管理线程池。

在创建线程池时,你可以使用不同的参数来配置线程池的行为。

以下是一些常见的线程池参数:1. corePoolSize(核心线程数):-定义了线程池中保持活动状态的最小线程数。

即使线程处于空闲状态,核心线程也会一直保持活动。

线程池在没有任务执行时也不会销毁这些核心线程。

2. maximumPoolSize(最大线程数):-定义了线程池中允许存在的最大线程数。

当工作队列已满并且有新任务提交时,线程池会创建新的线程,直到达到最大线程数。

3. keepAliveTime(线程空闲时间):-当线程池中的线程数超过核心线程数时,多余的空闲线程在被终止之前等待新任务的时间。

如果在这段时间内没有新任务到达,则这些空闲线程将被终止,直到线程数等于核心线程数。

4. TimeUnit(时间单位):-与`keepAliveTime` 一起使用,指定了时间的单位,可以是秒、毫秒、微秒等。

5. workQueue(工作队列):-用于保存等待执行的任务的队列。

线程池会从这个队列中取出任务来执行。

Java 提供了不同种类的队列,如`LinkedBlockingQueue`、`ArrayBlockingQueue` 等。

6. ThreadFactory(线程工厂):-用于创建新线程的工厂。

可以通过实现`ThreadFactory` 接口来自定义线程的创建过程。

7. RejectedExecutionHandler(拒绝策略):-定义了当工作队列和线程池的最大线程数都达到上限,无法处理新任务时的处理策略。

常见的策略包括抛出异常、丢弃任务、直接执行等。

这些参数可以在使用`ThreadPoolExecutor` 类或`Executors` 工厂类创建线程池时进行配置。

在springboot中使用java线程池ExecutorService的讲解

在springboot中使用java线程池ExecutorService的讲解

在springboot中使⽤java线程池ExecutorService的讲解1. 认识java线程池1.1 在什么情况下使⽤线程池?1.单个任务处理的时间⽐较短2.需处理的任务的数量⼤1.2 使⽤线程池的好处:1.减少在创建和销毁线程上所花的时间以及系统资源的开销2.如不使⽤线程池,有可能造成系统创建⼤量线程⽽导致消耗完系统内存1.3 线程池包括以下四个基本组成部分:1、线程池管理器(ThreadPool):⽤于创建并管理线程池,包括创建线程池,销毁线程池,添加新任务;2、⼯作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执⾏任务;3、任务接⼝(Task):每个任务必须实现的接⼝,以供⼯作线程调度任务的执⾏,它主要规定了任务的⼊⼝,任务执⾏完后的收尾⼯作,任务的执⾏状态等;4、任务队列(taskQueue):⽤于存放没有处理的任务。

提供⼀种缓冲机制。

1.4 线程池的核⼼参数ThreadPoolExecutor 有四个构造⽅法,前三个都是调⽤最后⼀个(最后⼀个参数最全)public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), defaultHandler);}public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,threadFactory, defaultHandler);}public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), handler);}// 都调⽤它public ThreadPoolExecutor(// 核⼼线程数int corePoolSize,// 最⼤线程数int maximumPoolSize,// 闲置线程存活时间long keepAliveTime,// 时间单位TimeUnit unit,// 线程队列BlockingQueue<Runnable> workQueue,// 线程⼯⼚ThreadFactory threadFactory,// 队列已满,⽽且当前线程数已经超过最⼤线程数时的异常处理策略RejectedExecutionHandler handler ) {if (corePoolSize < 0 ||maximumPoolSize <= 0 ||maximumPoolSize < corePoolSize ||keepAliveTime < 0)throw new IllegalArgumentException();if (workQueue == null || threadFactory == null || handler == null)throw new NullPointerException();this.corePoolSize = corePoolSize;this.maximumPoolSize = maximumPoolSize;this.workQueue = workQueue;this.keepAliveTime = unit.toNanos(keepAliveTime);this.threadFactory = threadFactory;this.handler = handler;}主要参数corePoolSize:核⼼线程数核⼼线程会⼀直存活,即使没有任务需要执⾏当线程数⼩于核⼼线程数时,即使有线程空闲,线程池也会优先创建新线程处理设置allowCoreThreadTimeout=true(默认false)时,核⼼线程会超时关闭maxPoolSize:最⼤线程数当线程数>=corePoolSize,且任务队列已满时。

由浅入深理解Java线程池及线程池的如何使用

由浅入深理解Java线程池及线程池的如何使用

由浅⼊深理解Java线程池及线程池的如何使⽤前⾔多线程的异步执⾏⽅式,虽然能够最⼤限度发挥多核计算机的计算能⼒,但是如果不加控制,反⽽会对系统造成负担。

线程本⾝也要占⽤内存空间,⼤量的线程会占⽤内存资源并且可能会导致Out of Memory。

即便没有这样的情况,⼤量的线程回收也会给GC带来很⼤的压⼒。

为了避免重复的创建线程,线程池的出现可以让线程进⾏复⽤。

通俗点讲,当有⼯作来,就会向线程池拿⼀个线程,当⼯作完成后,并不是直接关闭线程,⽽是将这个线程归还给线程池供其他任务使⽤。

接下来从总体到细致的⽅式,来共同探讨线程池。

总体的架构来看Executor的框架图:接⼝:Executor,CompletionService,ExecutorService,ScheduledExecutorService抽象类:AbstractExecutorService实现类:ExecutorCompletionService,ThreadPoolExecutor,ScheduledThreadPoolExecutor从图中就可以看到主要的⽅法,本⽂主要讨论的是ThreadPoolExecutor研读ThreadPoolExecutor看⼀下该类的构造器:public ThreadPoolExecutor(int paramInt1, int paramInt2, long paramLong, TimeUnit paramTimeUnit,BlockingQueue<Runnable> paramBlockingQueue, ThreadFactory paramThreadFactory,RejectedExecutionHandler paramRejectedExecutionHandler) {this.ctl = new AtomicInteger(ctlOf(-536870912, 0));this.mainLock = new ReentrantLock();this.workers = new HashSet();this.termination = this.mainLock.newCondition();if ((paramInt1 < 0) || (paramInt2 <= 0) || (paramInt2 < paramInt1) || (paramLong < 0L))throw new IllegalArgumentException();if ((paramBlockingQueue == null) || (paramThreadFactory == null) || (paramRejectedExecutionHandler == null))throw new NullPointerException();this.corePoolSize = paramInt1;this.maximumPoolSize = paramInt2;this.workQueue = paramBlockingQueue;this.keepAliveTime = paramTimeUnit.toNanos(paramLong);this.threadFactory = paramThreadFactory;this.handler = paramRejectedExecutionHandler;}corePoolSize :线程池的核⼼池⼤⼩,在创建线程池之后,线程池默认没有任何线程。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

java内置线程池 自定义线程池 异步计算结果(Future)
2.1Java内置线程池介绍
Java内置线程池原理剖析
我们要想自定义线程池,必须先了解线程池的工作原理,才能自己定义线程池; 这里我们通过观察java中ThreadPoolExecutor的源码来学习线程池的原理; (源码演示在idea中查看)
1.3使用线程池有哪些优势
使用线程池有哪些优势
1:线程和任务分离,提升线程重用性; 2:控制线程并发数量,降低服务器压力,统一管理所有线程; 3:提升系统响应速度,假如创建线程用的时间为T1,执行任务用的时间为T2,销毁线 程用的时间为T3,那么使用线程池就免去了T1和T3的时间;
1.4:线程池应用场景介绍
线程池中的所有线程都使用ThreadFactory来创建,这样的线程无需手动启动,自动执行; static ExecutorService newFixedThreadPool(int nThreads) 创建一个可重用固定线程数的线程池 static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory)
延迟时间单位是unit,数量是delay的时间后执行callable。 ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit)
2.3:Java内置线程池-ExecutorService介绍
ExecutorService接口是java内置的线程池接口,通过学习接口中的方法,可以快速的掌握java内置线程池的基本使用 常用方法: void shutdown() 启动一次顺序关闭,执行以前提交的任务,但不接受新任务。 List<Runnable> shutdownNow() 停止所有正在执行的任务,暂停处理正在等待的任务,并返回等待执行的任务列表。 <T> Future<T> submit(Callable<T> task) 执行带返回值的任务,返回一个Future对象。 Future<?> submit(Runnable task) 执行 Runnable 任务,并返回一个表示该任务的 Future。 <T> Future<T> submit(Runnable task, T result) 执行 Runnable 任务,并返回一个表示该任务的 Future。
创建一个可重用固定线程数的线程池且线程池中的所有线程都使用ThreadFactory来创建。 static ExecutorService newSingleThreadExecutor()
创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。 static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) 创建一个使用单个 worker 线程的 Executor,且线程池中的所有线程都使用ThreadFactory来创建。
2.1.3:线程池工作流程总结示意图
2.2:自定义线程池-参数设计分析
通过观察Java中的内置线程池参数讲解和线程池工作流程总结,我们不难发现,要设计一个好的线程池, 就必须合理的设置线程池的4个参数;那到底该如何合理的设计4个参数的值呢?我们一起往下看.
2.2.1:4个参数的设计: 1:核心线程数(corePoolSize)
1.1 什么是线程池
什么是池
1.1 什么是线程池
什么是线程池
线程池其实就是一种多线程处理形式,处理过程中可以将任务添加到队列中,然后 在创建线程后自动启动这些任务。这里的线程就是我们前面学过的线程,这里的任务 就是我们前面学过的实现了Runnable或Callable接口的实例对象;
1.2为什么使用线程池
创建一个单线程执行程序,它允许在给定延迟后运行命令或者定期地执行。 static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) 创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行。
应用场景介绍 1:网购商品秒杀 2:云盘文件上传和下载 3:12306网上购票系统等
总之 只要有并发的地方、任务数量大或小、每个任务执行时间长或短的都可以使用线程池; 只不过在使用线程池的时候,注意一下设置合理的线程池大小即可;(关于如何合理设置线 程池大小在后面的章节中讲解)
线程池使用

Contents
思考: 既然ExecutorService是一个接口,接口是无法直接创建对象的,那么我们该如何获取ExecutorService的对象呢?
2.3:Java内置线程池-ExecutorService获取
获取ExecutorService可以利用JDK中的Executors 类中的静态方法,常用获取方式如下: static ExecutorService newCachedThreadPool() 创建一个默认的线程池对象,里面的线程可重用,且在第一次使用时才创建 static ExecutorService newCachedThreadPool(ThreadFactory threadFactory)
为什么使用线程池
1.2为什么使用线程池
为什么使用线程池
使用线程池最大的原因就是可以根据系统的需求和硬件环境灵活的控制线程的数量, 且可以对所有线程进行统一的管理和控制,从而提高系统的运行效率,降低系统运行运 行压力;当然了,使用线程池的原因不仅仅只有这些,我们可以从线程池自身的优点上 来进一步了解线程池的好处;
2.1.1:ThreadPoolExecutor部分源码
昨构日造复方习法:
public ThreadPoolExecutor(int corePoolSize, //核心线程数量
int maximumPoolSize,// 最大线程数
long keepAliveTime, // 最大空闲时间
TimeUnit unit,
1:编写任务类(MyTask),实现Runnable接口; 2:编写线程类(MyWorker),用于执行任务,需要持有所有任务; 3:编写线程池类(MyThreadPool),包含提交任务,执行任务的能力; 4:编写测试类(MyTest),创建线程池对象,提交多个任务测试; 具体代码参考idea
小提示: 关于线程池的功能比较繁多,这里仅仅模拟了核心功能,其他功能大家可以自行思考补全;
(代码演示参考idea)
2.3:Java内置线程池-ScheduledExecutorService
ScheduledExecutorService是ExecutorService的子接口,具备了延迟运行或定期执行任务的能力, 常用获取方式如下: static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
4:最大空闲时间(keepAliveTime)
这个参数的设计完全参考系统运行环境和硬件压力设定,没有固定的参考值,用户可以根据经验和系统产生任务的时间间隔合理 设置一个值即可;
小提示:
上面4个参数的设置只是一般的设计原则,并不是固定的,用户也可以根据实际情况灵活调整!
2.2:自定义线程池-实现步骤
// 时间单位
BlockingQueue<Runnable> workQueue, // 任务队列
ThreadFactory threadFactory, // 线程工厂
RejectedExecutionHandler handler // 饱和处理机制
)
{ ... }
2.1.2:ThreadPoolExecutor参数详解
核心线程数的设计需要依据任务的处理时间和每秒产生的任务数量来确定,例如:执行一个任务需要0.1秒,系统百分之80的时间每 秒都会产生100个任务,那么要想在1秒内处理完这100个任务,就需要10个线程,此时我们就可以设计核心线程数为10;当然实际情况不可能这么平 均,所以我们一般按照8020原则设计即可,既按照百分之80的情况设计核心线程数,剩下的百分之20可以利用最大线程数处理;
2.3:Java内置线程池-ScheduledExecutorService
ScheduledExecutorService常用方法如下: <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit)
目标
TARGET
【理解】线程池基本概念 【理解】线程池工作原理 【掌握】自定义线程池 【应用】java内置线程池 【应用】使用java内置线程池完成综合案例
Contents

Hale Waihona Puke 线程池1. 线程池基础 2. 线程池使用 3. 线程池综合案例 4.学员练习 5.线程池总结
线程池基础
概念介绍 1:什么是线程池 2:为什么使用线程池 3:线程池有哪些优势
我们可以通过下面的场景理解ThreadPoolExecutor中的各个参数;
昨日复习
a客户(任务)去银行(线程池)办理业务,但银行刚开始营业,窗口服务员还未就位(相当于线程池中初始线程数量为0), 于是经理(线程池管理者)就安排1号工作人员(创建1号线程执行任务)接待a客户(创建线程); 在a客户业务还没办完时,b客户(任务)又来了,于是经理(线程池管理者)就安排2号工作人员(创建2号线程执行任务)接待b客户(又创建了一个新的线程); 假设该银行总共就2个窗口(核心线程数量是2); 紧接着在a,b客户都没有结束的情况下c客户来了,于是经理(线程池管理者)就安排c客户先坐到银行大厅的座位上(空位相当于是任务队列)等候, 并告知他: 如果1、2号工作人员空出,c就可以前去办理业务; 此时d客户又到了银行,(工作人员都在忙,大厅座位也满了)于是经理赶紧安排临时工(新创建的线程)在大堂站着,手持pad设备给d客户办理业务; 假如前面的业务都没有结束的时候e客户又来了,此时正式工作人员都上了,临时工也上了,座位也满了(临时工加正式员工的总数量就是最大线程数), 于是经理只能按《超出银行最大接待能力处理办法》(饱和处理机制)拒接接待e客户; 最后,进来办业务的人少了,大厅的临时工空闲时间也超过了1个小时(最大空闲时间),经理就会让这部分空闲的员工人下班.(销毁线程) 但是为了保证银行银行正常工作(有一个allowCoreThreadTimeout变量控制是否允许销毁核心线程,默认false),即使正式工闲着,也不得提前下班,所 以1、2号工作人员继续待着(池内保持核心线程数量);
相关文档
最新文档