线程池面试题总结

1 submit和execute有啥不同

  submit如果传入的任务是Runnable,会将Runnable包装成Callable,且返回值固定式null,并最终调用execute

public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        execute(ftask);
        return ftask;
    }

2 FutureTask 说说他的get方法

  任务状态主要有一下几种

private volatile int state;
    private static final int NEW          = 0;
    private static final int COMPLETING   = 1;
    private static final int NORMAL       = 2;
    private static final int EXCEPTIONAL  = 3;

get方法首先是支持多线程的,也就是说可以有多个线程都要获取这个执行结果

  如果此时state值不是NORMAL说明执行还没有完成,此时会将线程包装成WaitNode加入到阻塞队列,并将执行get方法的线程挂起。

  当执行完成后会自动的唤醒

public void run() {
        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);

  set方法就会唤醒的

3 线程池的参数

 1 coreSize 2 maxSize 3 keeplive时间 4 时间的单位 5 blockingqueue 6 threadFactory 7 拒绝策略

4 这几个参数的意义

Worker(Runnable firstTask) {
            setState(-1); // inhibit interrupts until runWorker
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this);//this说明Worker就是一个Runnable
        }

  对线程池提交任务,没达到coreSize之前,会一直addWorker,如果成功add了,在addWorker方法内就会执行Thread.start,执行的逻辑正好是Worker的run方法

  达到了coreSize之后,尝试往阻塞队列里添加任务

  如何阻塞队列满了,看maxSize是否大于coreSize,如果MaxSize大于coreSize,继续增加worker

5 maxSize小于coreSize会怎样

if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();

6 线程池的五个状态

  1 RUNNING

  2 SHUTDOWN

  3 STOP

  4 TIDYING 当最后一个线程退出会把状态赋值这个

  5 TERMINATED terminate方法有子类实现 默认啥都不干

7 worker继承了AQS,为什么要实现独占锁

  tryLock拿到锁,说明worker处于忙的状态

  这个独占锁是不可重入的,所以不能直接用ReentrantLock

8 worker在执行中如果有某个任务中断了当前线程怎么办

while (task != null || (task = getTask()) != null) {
                w.lock();
                // If pool is stopping, ensure thread is interrupted;
                // if not, ensure thread is not interrupted.  This
                // requires a recheck in second case to deal with
                // shutdownNow race while clearing interrupt
                if ((runStateAtLeast(ctl.get(), STOP) ||
                     (Thread.interrupted() &&
                      runStateAtLeast(ctl.get(), STOP))) &&
                    !wt.isInterrupted())
                    wt.interrupt();//清除中断

  

  

原文地址:https://www.cnblogs.com/juniorMa/p/13965993.html