JAVA 线程池原理---简洁代码实现

抽空自学了一下java线程池工作原理,简单记录一下。

说明:博主由于博客写的比较少,格式不熟练。下文贴的代码格式可能不是很好。

1.线程池的接口实现如下图所示(图片引用别处)

在这里插入图片描述

2.线程池的作用

线程池的工作主要是控制运行的线程数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果任务数量超过了最大线程数量,需要进入队列排队等候,等其他线程执行完毕,再从队列中取出任务来执行。

3.主要特点

a.线程复用
b.控制最大并发数量
c.管理线程

4.使用线程池的好处

a.降低了资源消耗。通过复用机制降低了线程创建和销毁的消耗。
b.提高了响应速度。当任务到达时,任务不需要等候就能立即执行。
c.提高了线程的可管理性。线程是稀缺的,如果无限制创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配,调优和监控。

5.自己实现线程池

5.1 思考?实现一个线程池需要什么?

  1. 存放任务的队列或者仓库

  2. 工作线程,不停的执行任务

  3. 线程容器,存放工作线程,便于管理

  4. 阻塞的提交任务方法

  5. 不阻塞的提交任务方法

  6. 线程池初始化

  7. 线程池销毁方法

5.2 源码实现

public class MyThreadPool{

	//存放任务的队列或者仓库
	private BlockingQueue<Runnable> blockingQueue;
	
	//线程容器,存放工作线程,便于管理
	private List<Thread> workers;
	//工作线程 需要包装一下
	public static class Worker extends Thread{
	
	 private MyThreadPool pool;
	  public Worker(MyThreadPool pool){
	            this.pool = pool ;
	        }

 	    @Override
        public void run() {
		//线程池不是停止状态 或者任务队列有队列时需要工作
            while (this.pool.isWorking || this.pool.blockingQueue.size()>0){

                Runnable task = null;

                    try {
                        if(this.pool.isWorking){
                            task = this.pool.blockingQueue.take();
                        }else
                            task = this.pool.blockingQueue.poll(); //非堵塞

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                if(task !=null){
                    task.run();
                }

            }

        }
 
}

	//线程池的初始化
	public MyThreadPool(int poolsize,int queueSize)  {

        if(poolsize<0 || queueSize<0){
            throw new IllegalArgumentException("非法参数");
        }
        this.blockingQueue =  new LinkedBlockingQueue<>();

        this.workers = Collections.synchronizedList(new ArrayList<Thread>());

        for(int i=0;i<poolsize;i++){
            Worker worker = new Worker(this);  // 实例化线程
            worker.start(); //开始执行任务
            this.workers.add(worker); //加入任务线程
        }
    }

	//提交任务 非阻塞

   public boolean submit(Runnable task){

        if(isWorking){
            if(this.blockingQueue.offer(task)){
                return true;
            }
        }

        return false;
    }
}

	// 提交任务 阻塞
	public void execute(Runnable task){
	        try {
	            if(isWorking){
	                this.blockingQueue.put(task);
	            }
	
	        } catch (InterruptedException e) {
	            e.printStackTrace();
	        }
    }


	//线程池的关闭条件
	 //任务无法加入
    //处理完所有任务
    //关闭时,不需要阻塞,没有任务需要处理
    //关闭时,阻塞得任务需要中断
    private volatile boolean isWorking = true;

    public void shutDown(){
        this.isWorking = false ;
        for(Thread th : workers){
            if(th.getState().equals(Thread.State.BLOCKED) || th.getState().equals(Thread.State.WAITING) ||
            th.getState().equals(Thread.State.TIMED_WAITING)){
                th.interrupt();
            }
        }


    }

5.3测试

 public static void main(String args[]) throws InterruptedException {
        MyThreadPool myThreadPool = new MyThreadPool(3,6);

        for (int i=0; i<50; i++){
            myThreadPool.submit(new Runnable() {
                public void run() {
                    System.out.println(Thread.currentThread()+"任务正在执行中。。。");
                    try {
                        Thread.sleep(2500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        /*Thread.sleep(15000);
        myThreadPool.shutDown();*/
    }

6.总结

本篇文章实现了一个简单的线程池,但是实际中的线程池工作原理已经和本文很类似了。结合线程池源代码进行阅读。应该可以很快的理解线程池源代码了。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值