【Java线程池ThreadPool(创建线程的第三种方式)】

本文详细介绍了Java线程池的概念、作用及实现方式,包括自定义线程池、拒绝策略、系统提供的各种线程池类型及其特点。同时,还探讨了线程池的常用方法,如execute、shutdown等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

优快云话题挑战赛第2期
参赛话题:一起学Java

线程池ThreadPool(创建线程的第三种方式)

1、线程池的作用

主要用于创建和管理若干个线程的一种容器,当我们需要执行任务时,可以从池中取出

线程来执行,当执行完任务后,将线程返回到池中,避免频繁的去创建和销毁线程,从而

节省空间,提升系统性能

2、自定义线程池

ThreadPoolExecutor pool=

new ThreadPoolExecutor(

核心线程数,

最大线程数,

超时(空闲,活跃)时间,

超时的时间单位,

任务队列,

线程工厂,

拒绝策略);

拒绝策略类型:

* 1》AbortPolicy:拒绝执行新的任务,并抛出异常

* 2》CallerRunsPolicy:如果线程池没有关闭,不使用线程池中的线程

* 也不会加入到任务队列,而是让当前线程直接调用run()方法来执行任务,

* 如果线程池已关闭,则直接丢弃掉该任务不执行

* 3》DiscardOldestPolicy: 如果线程池没有关闭,将任务队列中存放最久的任务

* (队首元素)移除掉,并将新的任务加入到任务队列中,如果线程池已经关闭

* 则直接丢弃掉该任务不执行

* 4》DiscardPolicy:拒绝执行任务,但是不会抛异常

3、jdk自带线程

1》单线程线程池

ExecutorService es=Executors.newSingleThreadExecutor()

只有一个核心线程,不允许创建非核心线程;

等上一个任务执行完了,才能执行下一个任务

2》固定数量线程池

ExecutorService es=Executors.newFixedThreadPool(int n);

传入的参数既是核心线程又是最大线程,

也就是不允许创建非核心线程

3》可缓存线程池

ExecutorService es=Executors.newCachedThreadPool();

没有核心线程,所有线程均为非核心线程

有多少任务就会创建多少个线程

线程最大数量为integer.max_value,

所有非核心线程空闲时间超过60S就会被回收

4》周期性线程池

ExecutorService es=Executors.newScheduledThreadPool(int n);

自己指定核心线程数

线程最大数量为integer.max_value

超时时间为0

任务队列为延迟队列

4、线程池的常用方法

1》execute(Runnable r)

将任务对象交给线程池,线程池会自动取出空闲线程来执行任务,

没有空闲线程就将任务加入到任务队列中,队列满了就触发拒绝策略

2》shutdown()

安全关闭线程池

只有等到线程池中所有线程都执行完任务后才会关闭

如果还有未执行完任务,当前方法会阻塞

3》shutdownNow();

立即关闭线程

无论线程池中是否还有未执行完的额任务,都会立即关闭线程池

会导致线程池还有未执行完的任务,返回这些未执行的线程

周期性线程中的主要方法

1》schedule(Runnable r,long delay, TimeUnit unit)

延迟指定时间后来执行这个r任务

2>scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit);

每间隔period指定的时间后来执行一次任务

如果一个任务的执行时间超过了间隔时间,

那么在一个任务执行完成红立即执行下一个任务,

如果没有超过,那么就在指定间隔时间后执行下一个任务

3》scheduleWithFixedDelay(Runnable command,long initialDelay,long delay,TimeUnit unit);

执行周期性任务

在一个任务执行完成后,再间隔设置的时间后,

再来执行下一个任务

import java.util.Date;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor.AbortPolicy;
import java.util.concurrent.TimeUnit;

/*
 * 线程池
 */
public class ThreadDemo16 {
	public static void main(String[] args) {
		//自定义线程池
		/**
		 * 参数解释:
		 * 1、corePoolSize:核心线程数
		 * 		线程池创建出来时就需要创建的线程数,线程池中需要保证最小数量线程
		 * 2、maximumPoolSize:最大线程数
		 * 		线程池中允许存在的最大线程数量
		 * 3、keepAliveTime:超时(空闲,活跃)时间
		 * 		非核心线程在指定时间内没有接收到新的任务,就会被销毁,
		 * 		如果调用了allowCoreThreadTimeOut()方法并且参数为true,
		 * 		那么超过指定时间后,核心线程也会被销毁
		 * 4、TimeUnit:keepAliveTime超时的时间单位
		 * 5、workQueue:任务队列
		 * 		需要线程池中的线程执行任务所存放的队列
		 * 6、threadFactory:线程工厂
		 * 		负责创建线程池中的线程
		 * 7、RejectedExecutionHandler:拒绝策略
		 * 		当线程池中所有线程都在执行任务,并且任务队列也是满负荷的情况下
		 * 		又有新的任务需要线程池来执行,就会触发拒绝策略
		 * 
		 * 拒绝策略类型:
		 * 1》AbortPolicy:拒绝执行新的任务,并抛出异常
		 * 2》CallerRunsPolicy:如果线程池没有关闭,不使用线程池中的线程
		 * 		也不会加入到任务队列,而是让当前线程直接调用run()方法来执行任务,
		 * 		如果线程池已关闭,则直接丢弃掉该任务不执行
		 * 3》DiscardOldestPolicy:	如果线程池没有关闭,将任务队列中存放最久的任务
		 * 		(队首元素)移除掉,并将新的任务加入到任务队列中,如果线程池已经关闭
		 * 		则直接丢弃掉该任务不执行
		 * 4》DiscardPolicy:拒绝执行任务,但是不会抛异常
		 */
//		ThreadPoolExecutor pool=
//		new ThreadPoolExecutor(
//				3,
//                3,
//                10,
//                TimeUnit.SECONDS,
//                new ArrayBlockingQueue<Runnable>(5),
//                new ThreadFactory() {
//					
//					@Override
//					public Thread newThread(Runnable r) {
//						return new Thread(r);
//					}
//				},
//               
//               new AbortPolicy());
//		
//		//创建任务对象,并交给线程池执行
//		//线程池会自动取出空闲线程来执行该任务
//		pool.execute(new ThreadTask("A"));
//		pool.execute(new ThreadTask("B"));
//		pool.execute(new ThreadTask("C"));
//		pool.execute(new ThreadTask("D"));
//		pool.execute(new ThreadTask("E"));
//		pool.execute(new ThreadTask("F"));
//		pool.execute(new ThreadTask("G"));
		
		System.out.println("_____________________________________________");
		//系统提供的线程池
		/**
		 * 1、创建单个线程的线程池
		 * 		只有一个核心线程,不允许创建非核心线程;
		 * 		等上一个任务执行完了,才能执行下一个任务
		 * 
		 */
//		ExecutorService es=
//				Executors.newSingleThreadExecutor();
		/**
		 * 2、创建固定的数量线程的线程池
		 * 		传入的参数既是核心线程又是最大线程,
		 * 		也就是不允许创建非核心线程
		 */
//		es=
//				Executors.newFixedThreadPool(5);
		/**
		 * 3、创建可缓存线程池
		 * 		没有核心线程,所有线程均为非核心线程
		 * 		有多少任务就会创建多少个线程
		 * 		线程最大数量为integer.max_value,
		 *		所有非核心线程空闲时间超过60S就会被回收
		 */
//		
//		es=
//				Executors.newCachedThreadPool();
//		
//		es.execute(new ThreadTask("A"));
//		es.execute(new ThreadTask("B"));
//		es.execute(new ThreadTask("C"));
//		es.execute(new ThreadTask("D"));
//		es.execute(new ThreadTask("E"));
//		es.execute(new ThreadTask("F"));
		
		/**
		 * 4、周期性线程池
		 * 		自己指定核心线程数
		 * 		线程最大数量为integer.max_value
		 * 		超时时间为0
		 * 		任务队列为延迟队列
		 */
		ScheduledExecutorService es=
				Executors.newScheduledThreadPool(3);
		/**
		 * 指定延迟多长时间之后来执行任务
		 * 
		 */
//		es.schedule(new Runnable() {
//			
//			@Override
//			public void run() {
//				System.out.println(new Date());
//			}
//		}, 5, TimeUnit.SECONDS);
		/**
		 * 2、执行周期性任务
		 * 参数解释
		 * 1》周期执行的任务
		 * 2》第一次执行任务的的延迟时间
		 * 3》两次任务执行时间的间隔时间
		 * 4》时间单位
		 * 
		 * 		如果一个任务的执行时间超过了间隔时间,
		 * 		那么在一个任务执行完成红立即执行下一个任务,
		 * 		如果没有超过,那么就在指定间隔时间后执行下一个任务
		 */
		System.out.println(new Date());
		es.scheduleAtFixedRate(new Runnable() {
			
			@Override
			public void run() {
				System.out.println(new Date());
			}
		}, 3, 1, TimeUnit.SECONDS);
		
		/**
		 * 3、执行周期性任务
		 *		 在一个任务执行完成后,再间隔设置的时间后,
		 * 		再来执行下一个任务
		 */
		
//		System.out.println(new Date());
//		es.scheduleWithFixedDelay(new Runnable() {
//			
//			@Override
//			public void run() {
//				try {
//					Thread.sleep(1000);
//				} catch (InterruptedException e) {
//					e.printStackTrace();
//				}
//				System.out.println(new Date());
//			}
//		}, 3, 1, TimeUnit.SECONDS);
		//关闭线程池
		/*
		 * 安全关闭线程池
		 * 只有等到线程池中所有线程都执行完任务后才会关闭
		 * 如果还有未执行完任务,当前方法会阻塞
		 */
//		es.shutdown();
		/*
		 * 立即关闭线程
		 * 无论线程池中是否还有未执行完的额任务,都会立即关闭线程池
		 * 会导致线程池还有未执行完的任务,返回这些未执行的线程
		 */
//		pool.shutdownNow();
	}	
}

//线程池需要执行的任务
class ThreadTask implements Runnable{
	private String name;
	public ThreadTask(String name) {
		this.name=name;
	}
	@Override
	public void run() {
		System.out.println(
				Thread.currentThread().getName()+"线程正在执行"+name+"任务");
	}
	@Override
	public String toString() {
		return "名称为"+name+"任务";
	}
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

God Zhang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值