手撕线程池

转载自https://mp.weixin.qq.com/s/xzBUIh9SSieoQqwdvMoIKg
Executor类

public interface Executor {    
	void execute(Runnable command);
}
/**

 * 自动动手写一个线程池

 */

public class MyThreadPoolExecutor implements Executor{
    /**
     * 线程池的名称
     */
    private String name;
    /**
     * 线程序列号
     */
    private AtomicInteger sequence = new AtomicInteger(0);
    /**
     * 核心线程数
     */

    private int coreSize;
    /**
     * 最大线程数
     */
    private int maxSize;   
    /**
     * 任务队列
     */
	private BlockingQueue<Runnable> taskQueue; 
	/**
     * 拒绝策略
     */ 
	private RejectPolicy rejectPolicy;  
	/**
     * 当前正在运行的线程数

     * 需要修改时线程间立即感知,所以使用AtomicInteger

     * 或者也可以使用volatile并结合Unsafe做CAS操作(参考Unsafe篇章讲解)
     */  
	private AtomicInteger runningCount = new AtomicInteger(0);
	public MyThreadPoolExecutor(String name, int coreSize,int maxSize, BlockingQueue<Runnable> taskQueue, RejectPolice rejectPolicy){
		this.name = name;
		this.coreSize = coreSize;       
   		this.maxSize = maxSize;
   	 	this.taskQueue = taskQueue;
   		this.rejectPolicy = rejectPolicy;
	}

	@Override
	public void execute(Runnable task){    
	// 正在运行的线程数       
	int count = runningCount.get();      
	// 如果正在运行的线程数小于核心线程数,直接加一个线程       
	if(count < coreSize){          
	// 注意,这里不一定添加成功,addWorker()方法里面还要判断一次是不是确	实小           
	if (addWorker(task, true)) {                
		return;        
	}            
	// 如果添加核心线程失败,进入下面的逻辑
	    
	}   
	// 如果达到了核心线程数,先尝试让任务入队       
	// 这里之所以使用offer(),是因为如果队列满了offer()会立即返回false        
	if (taskQueue.offer(task)) {          
		// do nothing,为了逻辑清晰这里留个空if       
	} else{           
		// 如果入队失败,说明队列满了,那就添加一个非核心线程           
		if(!addWorker(task, false)) {               
		// 如果添加非核心线程失败了,那就执行拒绝策略
   		rejectPolicy.reject(task, this);       
   		}     
	}
}  
	private boolean addWorker(Runnable newTask, boolean core) {   
	// 自旋判断是不是真的可以创建一个线程
  	   for(;;){         
	// 正在运行的线程数        
	int count = runningCount.get();         
	// 核心线程还是非核心线程         
	int max = core ? coreSize : maxSize;         
	// 不满足创建线程的条件,直接返回false          
	if(count >= max){          
		return false;          
	}
 
	// 修改runningCount成功,可以创建线程

	if(runningCount.compareAndSet(count, count + 1)) {
	// 线程的名字               
	String threadName = (core ?"core_" : "")+ name + 			sequence.incrementAndGet();              
	// 创建线程并启动               
	new Thread(() -> {System.out.println("thread name: 	"+Thread.currentThread().getName());                   
	// 运行的任务                   
	Runnable task = newTask;                   
	// 不断从任务队列中取任务执行,如果取出来的任务为null,则跳出循环,线程也就结束了                    
	while (task != null || (task = getTask()) != null) {                       
		try {                           
		// 执行任务
		  task.run();
		 }finally{                          
			// 任务执行完成,置为空
   			task = null ;
    	 }                   
		}                
	},threadName.start();              
			break;
		}       
	}        
	return true;   
}    
	private Runnable getTask(){       
		try {           
		// take()方法会一直阻塞直到取到任务为止
			return taskQueue.take();     
		}catch(InterruptedException e){            
		// 线程中断了,返回null可以结束当前线程           
		// 当前线程都要结束了,理应要把runningCount的数量减一
			runningCount.decrementAndGet();           
			return null;
		}   
	}
}

RejectPolicy拒绝策略接口

public interface RejectPolicy{
	void reject(Runnable task, MyThreadPoolExecutormyThreadPoolExecutor);
}

DiscardRejectPolicy丢弃策略实现类

/**
 * 丢弃当前任务
 */
public class DiscardRejectPolicy implements RejectPolicy{ 		@Override
	public void reject(Runnable task, MyThreadPoolExecutor myThreadPoolExecutor){
		// do nothing
		System.out.println("discard one task");   
	}	
}

测试类

public class MyThreadPoolExecutorTest{
	public static void main(String[] args){       
		Executor threadPool = new MyThreadPoolExecutor("test",5,10, new ArrayBlockingQueue<>(15),new DiscardRejectPolicy());
		AtomicInteger num = new AtomicInteger(0);      
		for(int i = 0; i < 100; i++){           
			threadPool.execute(()->{               
				try{
			  		Thread.sleep(1000);                    
					System.out.println("running: "+ System.currentTimeMillis() + ": "+ num.incrementAndGet());             
				} catch (InterruptedException e){
				    e.printStackTrace();                
				}
			 }); 	      
		}    
	}
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值