并发编程 - 线程池ThreadPoolExecutor、自定义实现线程池、定时任务、并发安全

为什么要使用线程池?
在Java中,创建一个线程只需要通过 new Thread(),就可以创建一个线程。那么创建一个线程需要经历以下几个步骤:

  • 1、创建(T1:向操作系统申请内存)
  • 2、运行(T2:执行run方法中业务)
  • 3、销毁(T3:销毁当前线程并释放资源)

所以,在每一次new出一个线程需要消耗的时间为T1+T2+T3,可以发现,只有运行的业务不同,其他时间都不属于业务处理时间,因此可以复用 。

使用线程池的好处

  • 可以降低资源的消耗

  • 提高响应速度

  • 提高线程的可管理性
    自己实现一个线程池(简化版ThreadPoolExecutor)
    在此,使用到了以下几个类:smallThreadPool(线程池实现)、testThreadPool(线程池测试类)、smallQueue(自定义实现队列,在并发编程 - 跳表、写时复制容器、阻塞队列中实现)

  • smallThreadPool类代码:

package threadPool;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;

import queue.smallQueue;
//简化版,移除最大线程数、线程过期时间、过期单位,仅保留四个参数
public class smallThreadPool implements ExecutorService {
   
	//定义一个存放任务的队列,此时使用我们之前写的queue,来处理
	private final BlockingQueue<Runnable> blockingQueue;
	//核心线程数
	private final Thread[] coreThreads;
	//已用线程数量
	private final AtomicInteger enableThreadCount = new AtomicInteger(-1);
	//未初始化线程数量
	private final AtomicInteger notInitThreadCount;
	//创建线程的工厂
	private ThreadFactory threadFactory;
	//任务满时淘汰策略
	private RejectedExecutionHandler rejectedExecutionHandler;
	public smallThreadPool() {
   
		this(10);//如果没有传参,初始化任务数量为100个,线程池容量为10个
	}
	//通过构造传参初始化队列大小、线程池大小,此处忽略数字校验
	public smallThreadPool(int coreThreadPoolSize,
			ThreadFactory threadFactory,BlockingQueue<Runnable> blockingQueue,RejectedExecutionHandler rejectedExecutionHandler) {
   
		this.blockingQueue = blockingQueue;
		this.coreThreads = new Thread[coreThreadPoolSize];
		this.threadFactory = threadFactory;
		this.rejectedExecutionHandler = rejectedExecutionHandler;
		this.notInitThreadCount = new AtomicInteger(coreThreadPoolSize);
		//先初始化核心线程
		for(int i=0;i<coreThreadPoolSize;i++){
   
			coreThreads[i] = threadFactory.newThread(new MyTaskThread());
			coreThreads[i].start();
		}
	}
	public smallThreadPool(int coreThreadPoolSize) {
   
		this(coreThreadPoolSize,Executors.defaultThreadFactory(),new smallQueue<>(coreThreadPoolSize),new RejectedExecutionHandler(){
   
			@Override
			public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
   
				throw new RuntimeException("任务["+r.toString() +"]超被抛弃了,因为当前没有空闲线程且队列已满了!");
			}
			
		});
	}
	//提交任务
	@Override
	public void execute(Runnable command) {
   
		if(blockingQueue.offer(command)){
   
			//添加成功
		}else{
   
			//添加失败,执行淘汰策略,由于是自定义实现,所以ThreadPoolExecutor不存在
			rejectedExecutionHandler.rejectedExecution(command, null);
		}
	}
	//关闭线程池
	@Override
	public void shutdown() {
   
		for(int i=0;i<coreThreads.length;i++){
   
			coreThreads[i].interrupt();
			coreThreads[i] = null;
		}
		blockingQueue.clear();
	}

	@Override
	public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
			throws InterruptedException, ExecutionException, TimeoutException {
   
		// TODO Auto-generated method stub
		return null;
	}
	//继承Thread,重写run方法,让线程运行时,可以由我们自己来管理
	private class MyTaskThread implements Runnable{
   
		@Override
		public void run() {
   
			Runnable r = null;
			while(!Thread.currentThread().isInterrupted()){
   
				try {
   
					r = blockingQueue.take();
					if(r != null)
						r.run();
					System.out.println(Thread.currentThread().getName() + " - " + r.toString() + " 完成!");
					r = null; //help GC
				} catch (InterruptedException e) {
   
					Thread.currentThread().interrupt();
				}
			}
		}
	}
}

  • testThreadPool类实现代码:
package threadPool;

import java.util.concurrent.TimeUnit;

public class testThreadPool {
   
	private static class MyTask implements Runnable{
   
		private String name;
		public MyTask(String name) {
   
			this.name = name;
		}
		public String getName(){
   
			return name;
		}
		@Override
		public void run() {
   
			try {
   
				System.out.println(Thread.currentThread().getName() + " - 处理:"+name);
				TimeUnit.MILLISECONDS.sleep(1000);
			} catch (InterruptedException e) {
   
				e.printStackTrace();
			}
		}
		@Override
		public String toString() 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值