线程池

线程池的作用:

管理控制:线程池可以更好的控制线程,使我们可以对线程的生命周期、初始化、运行状态、销毁等各个环节有一个把控。

系统资源:线程池可以控制线程的数量,根据任务的多少去对线程池中的线程个数进行添加或减少,可以回收空闲状态的线程,减少线程的频繁初始化和销毁,避免不必要的系统开销,节省系统资源。保障稳定性。

应用性能:线程池可以配合高并发容器的设置,异步多线程的去处理任务,提高应用服务的吞吐率、消费性能,也提高了单个线程的利用率。

兜底策略:线程池提供了很多拒绝策略以应对很多情况。记录日志什么的。

线程池有很多重载的方法来创建线程:

这里不一一赘述了,但是一些情景中,jdk自带的这些方法并不能完全符合我们开发的要求,所以需要我们自定义线程池,这样也更灵活。

	public static void main(String[] args) {
		ThreadPoolExecutor pool = new ThreadPoolExecutor(
				corePoolSize, 
				maximumPoolSize, 
				keepAliveTime, 
				unit, 
				workQueue, 
				threadFactory, 
				handler
		);
	}

自定义线程池,只需要new出来ThreadPoolExecutor对象就ok了,这个对象的构造方法很多,最全的有7个参数的构造方法,如上图。

corePoolSize:核心线程数。
maximumPoolSize:线程池最大可容纳多少个线程同时运行。

keepAliveTime:线程的存活时间,到达时间后线程就over了。

unit:时间戳,keppAliveTime的单位。

workQueue:这个队列是的作用是当线程池中线程已满,但是又有任务要运行时,就会把任务放到这个队列中。但是有界队列和无界队列是有区别的。

threadFactory:这个线程工厂就是自定义线程池任务运行的具体逻辑。

handler:这个地方一般做一些兜底策略,比如错误处理、异常处理等等,也就是当有界队列中线程已满而又有任务过来时,队列已经不能容纳任务了,就会在这个地方就行处理。

 

定义一个任务类:模拟任务运行的具体逻辑

public class Task implements Runnable{
	private Integer id;
	private Integer count;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public Integer getCount() {
		return count;
	}
	public void setCount(Integer count) {
		this.count = count;
	}
	public Task(Integer id, Integer count) {
		this.id = id;
		this.count = count;
	}
	public Task(Integer id) {
		this.id = id;
	}
	
	@Override
	public String toString() {
		return "当前任务的id为:" + this.id;
	}
	@Override
	public void run() {
		try {
			
			System.err.println("任务运行:" + this.id);
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}
	
}

然后自定义线程池,进行测试:

	public static void main(String[] args) {
		ThreadPoolExecutor pool = new ThreadPoolExecutor(
				2, //coresize 核心线程数
				3, //maxmumPoolSize 线程池的最大上线21\
				60, //线程的存存活时间
				TimeUnit.SECONDS, 
				//new ArrayBlockingQueue<>(2), 
				new LinkedBlockingQueue<Runnable>(),
				new ThreadFactory() { //线程工厂,用户获取一个新的线程,把该线程投递到线程池中去
					@Override
					public Thread newThread(Runnable r) {
						Thread th = new Thread(r,"order-thread");
						if(th.getPriority() != Thread.NORM_PRIORITY) {
							th.setPriority(Thread.NORM_PRIORITY);
						}
						if(th.isDaemon()) {
							th.setDaemon(false);
						}
						return th;
					}
				}, 
				new RejectedExecutionHandler() { //拒绝策略
					
					@Override
					public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
						System.err.println("任务已经被拒绝..." + r.toString());
					}
				}
		);
		
		Task task1 = new Task(1);
		Task task2 = new Task(2);
		Task task3 = new Task(3);
		Task task4 = new Task(4);
		Task task5 = new Task(5);
		Task task6 = new Task(6);
		
		pool.execute(task1);
		pool.execute(task2);
		pool.execute(task3);
		pool.execute(task4);
		pool.execute(task5);
		pool.execute(task6);
		pool.shutdown();
	}

测试结果:

1、无界队列:总会按顺序2个2个的运行,因为核心线程数是2。

2、有界队列:当超出队列容量时就会走handler。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值