JAVA线程池应用

本文探讨了为何使用线程池,指出线程过多带来的问题,并介绍了线程池的原理,包括线程池管理器、工作线程、任务接口和任务队列。详细讲解了线程池API,如Executor、ExecutorService、ScheduledExecutorService及其具体实现类ThreadPoolExecutor和ScheduledThreadPoolExecutor,还分析了ScheduledExecutorService的定时任务执行方式。此外,提到了Executors工具类提供的线程池创建方式,如newFixedThreadPool、newCachedThreadPool、newSingleThreadExecutor和newScheduledThreadPool。最后讨论了确定线程池合适线程数量的方法,建议计算型任务使用CPU数量的1-2倍,而IO型任务则需要更多线程。
摘要由CSDN通过智能技术生成

–为甚么要用线程池?

线程是不是越多越好?
1、线程在java中是一个对象,更是操作系统的资源,线程创建、销毁需要时间。
如果创建时间+销毁时间>执行任务时间 就很不合算。
2、java对象占用堆内存,操作系统线程占用系统内存,根据jvm规范,一个线程默认
最大栈大小1M,这个栈空间是需要从系统内存中分配的。线程过多,会消耗很多的内存。
3、操作系统需要频繁切换线程上下文,影响性能。

–线程池原理 - 概念
1、线程池管理器:用于创建并管理线程池,包括创建线程池,销毁线程池,添加新任务;
2、工作线程:线程池中线程,在没有任务时处于等待状态,可以循环的执行任务‘
3、任务接口:每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,
任务执行完后的收尾工作,任务的执行状态等。
4、任务队列:用于存放没有处理的任务。提供一种缓存机制。

–线程池API - 接口定义和实现类
类型 名称 描述
接口 Executor 最上层的接口,定义了执行任务的方法execute
接口 ExecutorService 继承了Executor接口,拓展了Callable、Future、关闭方法
接口 ScheduledExecutorService 继承了ExecutorService,增加了定时任务相关的方法
实现类 ThreadPoolExecutor 基础、标准的线程池实现
实现类 ScheduledThreadPoolExecutor 继承了ThreadPoolExecutor,实现了ScheduledExecutorService中相关定时任务的方法

可以认为ScheduledThreadPoolExecutor是最丰富的实现类

	ExecutorService

//监测ExecutorService是否已经关闭,直到所有任务完成执行,或超时发生,或当前线程被中断
awaitTermination(Long timeout,TimeUnit unit)
//执行给定的任务集合,执行完毕后,返回结果
invokeAll(Collection<? extends Callable<T>> tasks)
//执行给定的任务合集,执行完毕或者超时后,返回结果,其他任务终止
invokeAll(Collection<? extends Callable<T>> tasks,TimeUnit unit)
//执行给定的任务,任意一个执行成功则返回结果,其他任务终止
invokeAny(Collection<? extends Callable<T>> tasks)
//执行给定的任务,任意一个执行成功或者超时后,则返回结果,其他任务终止
invokeAny(Collection<? extends Callable<T>> tasks,long timeout,TimeUnit unit)
//如果此线程池已关闭,则返回true
isShutdown()
//如果关闭后所有任务都已完成,则返回true
isTerminated()
//优雅关闭线程池,之前提交的任务将被执行,但是不会接受新的任务
shutdown()
//尝试体制所有正在执行的任务,停止等待任务的处理,并返回等待执行任务的列表
shutdownNow()
//提交一个用于执行的Callable返回任务,并返回一个Future,用于获取Callable执行结果
submit(Callable<T> task)
//提交可运行任务以执行,并发回一个Future对象,执行结果为null
submit(Runnable task)
//提交可运行任务以执行,并返回Future,执行结果为传入的result
submit(Runnable task,T result)

–ScheduledExecutorService 定时任务
---------------创建并执行一个一次性任务过了延迟时间就会被执行
schedule(Callable callable,long delay,TimeUnit unit)
schedule(Runnable command,long delay,TimeUnit unit)
---------------创建周期性任务
过了给定的初始延迟时间,会第一次被执行,执行过程中发生了异常,那么任务就停止
一次任务执行时长超过了周期时间,下一次任务会等到该次任务执行结束,立刻执行,
这就是它和scheduleWithFixedDelay的重要区别
------scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit)
过了初试延迟时间,第一次被执行,后续以给定的周期时间执行,执行过程中发生了异常,那么任务就停止
一次任务执行时长超过了周期时间,下一次任务会在该次任务执行结束的时间基础上,计算执行延时。
对于超过周期的长时间处理任务的不同处理方式,这是它和scheduleAtFixedRate的重要区别
------scheduleWithFixedDelay(Runnable command,long initialDelay,long period,TimeUnit unit)

线程池API -Executors工具类
你可以自己实例化线程池,也可以用Executors创建线程池的工厂类,常用方法如下:
newFixedThreadPool(int nThreads)创建一个固定大小、任务队列容量误解的线程池。核心线程数=最大线程数。
newCachedThreadPool()创建的是一个大小无界的缓冲线程池。它的任务队列时一个同步队列。
任务加入到池中,如果池中有空闲线程,则用空闲线程执行,如无则创建新线程执行。
池中的线程空闲超过60秒,则被销毁释放。线程数随任务的多少变化。
适用于执行耗时较小的异步任务。池的核心线程数=0,最大线程数=Integer.MAX_VALUE
newSingleThreadExecutor()只有一个线程来执行无界任务队列的单一线程池。
该线程池确保任务按加入的顺序一个一个依次执行。当唯一的线程因任务异常中止时,
将创建一个新的线程来继续执行后续的任务。与newFixedThreadPool(1)的区别在于,
单一线程池的池大小在newSingThreadExecutor方法中硬编码,不能再改变的。
newScheduledThreadPool(int corePoolSize)能定时执行任务的线程池。该池的核心线程数由参数指定,
最大线程数=Integer.MAX_VALUE

package day03;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/** 线程池的使用*/
public class Demo2 {
   
	/**
	 * 测试:提交15个执行时间需要3秒的任务,看线程池的状况
	 * @throws InterruptedException  传入不同的线程池,看不同的结果
	 * 
	 */
	public void testCommon(ThreadPoolExecutor threadPoolExecutor) throws InterruptedException {
   
		//测试:提交15个执行时间需要3秒的任务,看超过大小的2个,对应的处理情况
		for(int i=0;i<15;i++) {
   
			int n=i;
			threadPoolExecutor.submit(new Runnable() {
   

				@Override
				public void run() {
   
					// TODO Auto-generated method stub
					try {
   
						System.out.println("开始执行:"+n);
						Thread.sleep(3000L);
						System.out.println("执行结束:"+n);
					} catch (InterruptedException e) {
   
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				
			});
			System.out.println("任务提交成功:"+i);
		}
		//查看线程数量,查看队列等待数量
		Thread.sleep(500L);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值