线程池源码详细解读(下)

前文回顾AQS源码详细解读 ReentrantLock源码详细解读 LinkedBlockingQueue源码详细解读 线程池源码详细解读(上)接着上一篇文章,知道线程池的一些相关概念后,一起来看看实现原理吧。本文讲述ThreadPoolExecutor源码,力求理清执行顺序,尽量保持思路清晰,请耐心看完~文章导读内部类-Worker(基本属性,构造方法,AQS相关钩子方法,...
摘要由CSDN通过智能技术生成

前文回顾

接着上一篇文章,知道线程池的一些相关概念后,一起来看看实现原理吧。
本文讲述ThreadPoolExecutor源码,力求理清执行顺序,尽量保持思路清晰,请耐心看完~

文章导读

  • 内部类-Worker(基本属性,构造方法,AQS相关钩子方法,线程中断方法)
  • 提交任务(execute,addWorker)
  • 执行任务(runWorker)
  • 关闭方法(tryTerminated,shutdown,shutdownNow)

一、内部类-Worker

Worker表示线程池中的每一个任务,与线程一一对应。是AQS的子类,实现其独占模式,封装一些了对于资源操作的方法。

1.1 基本属性

重要的是thread(当前worker线程),firstTask(初始任务),completedTasks(任务计数器)。

    private final class Worker
        extends AbstractQueuedSynchronizer
        implements Runnable
    {
        /**
         * 这个类永远不会被序列化,设置serialVersionUID
         * 是为了停止javac编译器的警告
         */
        private static final long serialVersionUID = 6138294804551838833L;

        //表示一个工作线程,null则说明线程工厂创建出错了
        final Thread thread;
        //需要运行的初始任务,可能为空
        Runnable firstTask;
        //每个线程的任务计数器,表示完成的任务数量
        volatile long completedTasks;
        ......
     }

1.2 构造方法

Worker在第一次接收任务的时候被线程工厂创建,其中成员变量thread就是基于Worker的线程。

        Worker(Runnable firstTask) {
            //设置AQS.state为-1表示在运行之前禁止被中断
            setState(-1);
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this);
        }

1.3 对AQS相关方法的实现

Worker既然继承了AbstractQueuedSynchronizer,就一定会有相关钩子方法的实现。钩子方法是isHeldExclusively(),tryAcquire(int unused),tryRelease(int unused)。而lock(),tryLock(),unlock(),isLocked()都是对他们的进一步封装,非常的简练。如果有兴趣可以回忆回忆ReentrantLock都是怎么实现的,比较一下区别。

state表示当前线程的运行状态,总共有3种情况:

  • -1,表示在运行之前禁止被中断。
  • 0,表示锁没有被任何线程获取。
  • 1,表示锁已经被占有。
        //是否持有独占锁,根据state判断
        //state 0:表示锁没有被任何线程获取
        //state 1:表示锁已经被占有
        protected boolean isHeldExclusively() {
            return getState() != 0;
        }
        //尝试获取锁,成功后设置当前线程为锁的持有者
        protected boolean tryAcquire(int unused) {
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }
        //释放锁
        protected boolean tryRelease(int unused) {
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }
        //会先调用tryAcquire(1),若拿不到锁则阻塞获取锁资源
        public void lock()        { acquire(1); }
        //尝试获取锁,不会阻塞
        public boolean tryLock()  { return tryAcquire(1); }
        //会先调用tryRelease(1),若释放成功则去等待队列从队尾向前找下一个需要唤醒的节点
        public void unlock()      { release(1); }
        public boolean isLocked() { return isHeldExclusively(); }

1.4 对线程的中断方法

interruptIfStarted():用于中断工作线程,保证要中断的thread必须是已经初始化完成的,而且已经运行了。需要注意的是,Worker的构造方法中将state设置为-1。

        void interruptIfStarted() {
            Thread t;
            //确保线程已经运行并且中断标志为还是false时,就执
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值