zoukankan      html  css  js  c++  java
  • 线程池面试题总结

    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();//清除中断

      

      

  • 相关阅读:
    CentOS7和Ubuntu下安装Docker & Docker-Compose
    【译】ModSecurity
    【译】ModSecurity事务生命周期
    开源WAF工具ModSecurity
    RHEL/CentOS 安装最新版Nginx
    Linux流量监控工具iftop & nload
    Docker安全扫描工具之docker-bench-security
    wireshark抓包如何查看视频分辨率和码率
    【译】如何使用docker-compose安装anchore
    Docker安全扫描工具之DockerScan
  • 原文地址:https://www.cnblogs.com/juniorMa/p/13965993.html
Copyright © 2011-2022 走看看