线程池submit方法源码解析

本文是线程池的submit方法的源码解析,可以先看下【线程池execute方法的源码解析】

先了解下两个接口类

Callable类

package java.util.concurrent;
public interface Callable<V> {
 
    //返回结果,如果无法执行,则抛出异常。
    V call() throws Exception;
}

Future类

package java.util.concurrent;


public interface Future<V> {

    //试图取消此任务的执行。如果任务已完成、已取消或由于某些原因无法取消,则尝试取消失败。如果任务未启动时尝试取消成功,那么这个任务就永远不能运行。如果任务已经启动,则根据mayInterruptIfRunning参数确定是否要中断该任务的线程,阻止任务的执行。
    boolean cancel(boolean mayInterruptIfRunning);

    //如果任务在正常完成之前被取消,则返回true
    boolean isCancelled();

    //任务是否完成,完成返回true
    boolean isDone();

    //等待计算完成,然后检索其结果。
    V get() throws InterruptedException, ExecutionException;

    //在给定的时间等待计算完成,然后检索其结果
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

AbstractExecutorService类中submit的方法

1)、ExecutorService中接口,顶层入口;

package java.util.concurrent;
public interface ExecutorService extends Executor { 
    //其他接口省略

    <T> Future<T> submit(Callable<T> task);
}

2)、AbstractExecutorService类中submit方法,AbstractExecutorService实现了ExecutorService,有abstract修饰,并未实现所有方法; 

package java.util.concurrent;
public abstract class AbstractExecutorService implements ExecutorService { 
    //其他方法省略
    
      public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }
}

3)、newTaskFor(Callable<T> callable),AbstractExecutorService中方法,返回给定可调用任务的RunnableFuture对象;

    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        return new FutureTask<T>(callable);
    }

4)、FutureTask(Callable<V> callable),构造方法;

    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }

FutureTask中的任务状态

    * Possible state transitions:
    * NEW -> COMPLETING -> NORMAL 正常
    * NEW -> COMPLETING -> EXCEPTIONAL 异常
    * NEW -> CANCELLED 取消
    * NEW -> INTERRUPTING -> INTERRUPTED 中断
    //state用来记录FutureTask内部任务的执行状态
    private volatile int state;
    //新任务的初始状态
    private static final int NEW          = 0;
    //任务已经执行完成或者执行任务过程中发生异常,执行结果还没有赋值给outcome字段时的状态
    private static final int COMPLETING   = 1;
    //任务已经执行完成并且任务执行结果已经保存到outcome字段时的状态
    private static final int NORMAL       = 2;
    //任务执行发生异常并且异常原因已经保存到outcome字段时的状态
    private static final int EXCEPTIONAL  = 3;
    //任务未执行或者进行中,调用cancel(false)方法取消任务但是不中断任务执行线程时的状态
    private static final int CANCELLED    = 4;
    //任务未执行或者进行中,调用cancel(false)方法取消任务,要中断任务执行线程还没有中断时的状态
    private static final int INTERRUPTING = 5;
    //中断任务执行线程后的状态
    private static final int INTERRUPTED  = 6;

 5)、run(),执行方法;

  public void run() {
        //状态如果不是NEW,说明任务已执行/已被取消;状态如果是NEW,尝试把当前执行线程保存在runner字段中,保存失败;以上两种情况直接返回
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return;
        try {
            Callable<V> c = callable;
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    result = c.call();//任务执行
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    setException(ex);//异常
                }
                if (ran)
                    set(result);
            }
        } finally {
            // runner must be non-null until state is settled to
            // prevent concurrent calls to run()
            runner = null;
            // state must be re-read after nulling runner to prevent
            // leaked interrupts
            int s = state;
            if (s >= INTERRUPTING)//任务被中断,执行中断操作
                handlePossibleCancellationInterrupt(s);
        }
    }

6)、setException(Throwable t),任务执行异常,修改状态并保存异常信息;

    protected void setException(Throwable t) {
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {//状态从NEW改成COMPLETING
            outcome = t;//将异常赋值给outcome字段
            UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // 状态改成EXCEPTIONAL
            finishCompletion();//移除并通知所有等待的线程
        }
    }

7)、finishCompletion(),移除并通知所有等待的线程;

    private void finishCompletion() {
        // assert state > COMPLETING;
        //依次遍历waiters链表,唤醒节点中的线程,然后把callable置空
        for (WaitNode q; (q = waiters) != null;) {
            if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) {
                for (;;) {
                    Thread t = q.thread;
                    if (t != null) {
                        q.thread = null;
                        LockSupport.unpark(t);
                    }
                    WaitNode next = q.next;
                    if (next == null)
                        break;
                    q.next = null; // unlink to help gc
                    q = next;
                }
                break;
            }
        }

        done();

        callable = null;        // to reduce footprint
    }

8)、set(V v),任务成功执行,修改状态并保存执行结果;

    protected void set(V v) {
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {//状态从NEW改成COMPLETING
            outcome = v;//将结果赋值给outcome 字段
            UNSAFE.putOrderedInt(this, stateOffset, NORMAL); //状态设置为NORMAL
            finishCompletion();
        }
    }

9)、 handlePossibleCancellationInterrupt(int s),执行中断操作;

 private void handlePossibleCancellationInterrupt(int s) {
        // It is possible for our interrupter to stall before getting a
        // chance to interrupt us.  Let's spin-wait patiently.
        if (s == INTERRUPTING)
            while (state == INTERRUPTING)
                Thread.yield(); // wait out pending interrupt

        // assert state == INTERRUPTED;

        // We want to clear any interrupt we may have received from
        // cancel(true).  However, it is permissible to use interrupts
        // as an independent mechanism for a task to communicate with
        // its caller, and there is no way to clear only the
        // cancellation interrupt.
        //
        // Thread.interrupted();
    }

 ScheduledThreadPoolExecutor中的submit方法

    public <T> Future<T> submit(Callable<T> task) {
        return schedule(task, 0, TimeUnit.NANOSECONDS);
    }

跟execute方法的实现类似,这里不多说。

submit方法的使用

package com.su.mybatis.oracle.controller;
 
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;
 
public class Test {
 
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static void main(String[] args) {
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
        boolean flag = true;
        for(int i = 0;i<3;i++){
            final int num  = i;
            Future<Boolean> future = fixedThreadPool.submit(new Callable() {
                @Override
                public Boolean call() throws Exception {
                    System.out.println(Thread.currentThread().getName() + "正在执行,num = " + num);
                    if(num == 2) {
                        return false;
                    }else {
                        return true;
                    }
                }
            });
            try {
                System.out.println(future.get());
                flag = flag && future.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        System.out.println("flag:" + flag);
        fixedThreadPool.shutdown();
        System.out.println("main执行完成");
    }
}

输出结果:

pool-1-thread-1正在执行,num = 0
true
pool-1-thread-2正在执行,num = 1
true
pool-1-thread-3正在执行,num = 2
false
flag:false
main执行完成

 

 

如果有写的不对的地方,请大家多多批评指正,非常感谢!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值