关于java:java-线程池简述

42次阅读

共计 2831 个字符,预计需要花费 8 分钟才能阅读完成。

java 中的池化技术能够在咱们开拓新的线程之前提前为咱们筹备好,从而缩小了零碎的开销。线程池帮咱们对线程对立治理,同时也进步了零碎的响应。jdk concurrent 中的 Executors 类为咱们提供了创立线程池的办法,简略易用。次要有以下几个办法:

  1. newFixedThreadPool(int nThreads) 固定线程数的线程池;
  2. newSingleThreadExecutor() 只产生单个线程的线程池;
  3. newCachedThreadPool 缓存类型的线程池,线程数量可伸缩,非固定;

先来说下,除了这些 jdk 给咱们封装好的办法外,咱们能够本人手动创立线程池,本人创立能够加深咱们对这部分常识的印象,咱们能够通过调用 ThreadPoolExecutor 的构造方法来创立:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

看下他的重载结构器:

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

它的的构造方法中,次要有这么几个重要的参数:

  1. corePoolSize 线程池的外围线程数;
  2. maximumPoolSize 线程池的最大线程数;
  3. keepAliveTime 闲置线程存货工夫,超过这个工夫将会被回收(超过外围线程数的局部);
  4. unit 工夫单位;
  5. workQueue 阻塞队列,当线程数超过外围线程数时,工作将会被放入队列中;
  6. threadFactory 线程工厂,用于创立线程,个别应用它默认的外部类,ThreadPoolExecutor 没有提供该字段的 setter/getter 办法;
  7. handler 回绝策略,当阻塞队列满,并且超过最大线程数时,将会执行回绝策略的 reject 办法。

    看一下线程池执行线程的 execute 办法:

    public void execute(Runnable command) {if (command == null)
            throw new NullPointerException();
            
        int c = ctl.get();
        // 如果工作线程数小于外围线程数,调用 addWorker 办法后间接返回
        if (workerCountOf(c) < corePoolSize) {if (addWorker(command, true))
                return;
            c = ctl.get();}
        // 超过了外围线程数,优先增加到阻塞队列中
        if (isRunning(c) && workQueue.offer(command)) {int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            // 阻塞队列满,新建线程(每个线程都是一个 worker)并增加到 workers。else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        // 阻塞队列满,并且线程数大于最大线程数,调用 handler 的 rejectedExecution 办法。else if (!addWorker(command, false))
            reject(command);
    }

再来看下线程池的回绝策略,ThreadPoolExecutor,有个属性 defaultHandler,即默认的回绝策略。该类型为 AbortPolicy:其 rejectedExecution 办法是抛出异样。

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {throw new RejectedExecutionException("Task" + r.toString() +
                                                 "rejected from" +
                                                 e.toString());
        }

DiscardPolicy:什么都不做,放弃本次的工作

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {}

DiscardOldestPolicy:摈弃后面的工作,把新的工作退出到缓存队列中:

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {if (!e.isShutdown()) {
                // 弹出最后面的工作
                e.getQueue().poll();
                // 执行新的工作
                e.execute(r);
            }
        }

CallerRunsPolicy:由调用线程执行 run 办法:

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {if (!e.isShutdown()) {
                // 能够看到只是以后线程调用了 run 办法,并没有新建线程。r.run();}
        }

小结:

 次要简述了线程池罕用的创立办法、ThreadPoolExecutor 的结构器及七个参数的意义,同时也论述了四种回绝策略的作用及原理。

正文完
 0