Java基础-线程池

前言

在一个应用程序中,我们需要多次使用线程,也就意味着,我们需要多次创建并销毁线程。而创建并销毁线程的过程势必会消耗内存。而在Java中,内存资源是及其宝贵的,所以,我们就提出了线程池的概念。

线程池

那么什么是线程池 ?顾名思义,线程池就是一个装线程的池子,用来管理线程的创建和回收,重复利用等等,从而达到减少内存消耗的目的。

创建线程池

线程池的最上层接口是Executor,Executor接口有一个子接口ExecutorService,ExecutorService的实现类为AbstracExecutorService,而ThreadPoolExcutor正是AbstrcExecutorService的子类。ThreadPoolExecutor是线程池的核心类,此类的构造方法如下:

//线程池最上层接口
public interface Executor {
    void execute(Runnable command);
}

//创建线程使用的实现类
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) 
传参详解
  • corePoolSize:核心线程池大小。线程池默认存在的线程数量,即使空闲状态也不会被回收。

  • maximumPoolSize:线程最大数量。当新任务进来时,此时核心线程池和缓存队列已经,程序就会创建新的线程执行当前任务,但是数量不能大于maximumPoolSize这个值,否则会采用拒绝接收任务策略。这些线程称为非核心线程

  • keepAliveTime:非核心线程可存在的空闲时间。当非核心线程运行完毕就会进入空闲状态,空闲状态的线程超过一定时间会被回收以保证内存的节省。

  • unit:时间单位。和keepAliveTime配合使用。

  • workQueue:缓存队列,用来存放等待被执行的任务。

  • threadFactory:线程工厂,用来创建线程,一般有三种策略。

    ArrayBlockingQueue;
    LinkedBlockingQueue;
    SynchronousQueue;
    
  • handler:拒绝策略。线程的数量大于线程最大数量就会拒绝处理任务,有以下几种策略:

    ThreadPoolExecutor.AbortPolicy://不执行新任务并抛出RejectedExecutionException异常。 
    ThreadPoolExecutor.DiscardPolicy://不执行新任务,但是不抛出异常。 
    ThreadPoolExecutor.DiscardOldestPolicy://丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
    ThreadPoolExecutor.CallerRunsPolicy://直接调用executor方法来处理当前任务
    

线程池运行流程

当有新任务进入时,程序会先判断核心线程池是否已满,不是则创建新线程(核心线程)执行任务,如果已满就会判断缓存队列是否已满,未满则将任务存储在缓存队列中等待调用执行,如果缓存队列也满了,就会判断线程池的线程总数量是否已满,未满则创建非核心线程执行当前任务,否则就调用拒绝策略处理无法执行的任务。

常用线程池

定长线程池

定长线程池顾名思义就是固定长度的线程池。固定长度线程池有核心线程,核心线程的数据就是最大线程的数量,没有非核心线程。

示例代码
public class FixedThread {

	public static void main(String[] args) {
		
		// 创建固定长度的线程池
		ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
		for (int i = 0; i < 10; i++) {
			fixedThreadPool.execute(new Runnable() {
				
				@Override
				public void run() {
					// TODO Auto-generated method stub
					System.out.println(Thread.currentThread().getName()+"正在被执行!");
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			});
		}
	}
	
}
缓存线程池

可缓存的线程池,里边没有核心线程,非核心线程的数量没有上限,多少都可以。当有任务时创建线程执行任务,执行完毕线程会被回收。适用于任务量的情况。

示例代码
public class CacheThread {

	public static void main(String[] args) {

		// 创建可缓存的线程池
		ExecutorService cacheThreadPool = Executors.newCachedThreadPool();
		for (int i = 0; i < 10; i++) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			cacheThreadPool.execute(new Runnable() {
				@Override
				public void run() {
					// TODO Auto-generated method stub
					System.out.println(Thread.currentThread().getName() + "正在被执行!");
				}
			});
		}
	}
}
单线程池

创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(先进先出)执行。

示例代码
public class SingleThread {

	public static void main(String[] args) {
		
		//创建单线程池
		ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
		
		for (int i = 0; i < 10; i++) {
			final int index = i;
			singleThreadPool.execute(new Runnable() {
				@Override
				public void run() {
					// TODO Auto-generated method stub
					System.out.println(Thread.currentThread().getName()+"正在被执行!打印的值是"+index);
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			});
		}
	}
}
定时线程池

定时执行任务的线程池,按照某种特定的计划执行线程中的任务,有核心线程,但也有非核心线程,非核心线程的大小也为无限大。适用于执行周期性的任务。

示例代码
public class ScheduledThread {

	public static void main(String[] args) {
		// 创建可定时的固定长度线程池
		ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
		/**
		 * 	延迟参数详解
		 * scheduledThreadPool.schedule(command, delay, unit)
		 * 	参数1->new Runnable()
		 * 	参数2->延迟时间
		 * 	参数3->时间单位
		 * 
		 *	定时参数详解
		 * scheduledThreadPool.scheduleAtFixedRate(command, initialDelay, period, unit)
		 *	参数1->new Runnable()
		 * 	参数2->延迟时间
		 * 	参数3->定时时间
		 * 	参数4->时间单位
		 */
		scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				System.out.println(Thread.currentThread().getName() + "延迟1秒执行!");
			}
		}, 0,3, TimeUnit.SECONDS);
	}
}

文尾

文章均为学习阶段记录笔记,若有不妥请留言指正。谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值