前言

参考链接

1.ThreadPoolExecutor继承关系

2. Executor 接口

executor是一个顶层接口。

2.1 Executor 源码

public interface Executor {void execute(Runnable command);
}

Executor 接口只有一个核心方法 execute() ,参数为Runnable接口,没有返回值。

2.2 Runnable 源码

@FunctionalInterface
public interface Runnable {public abstract void run();
}

2.3 ThreadPoolExecutor的execute实现

 public void execute(Runnable command) {//参数校验      if (command == null)throw new NullPointerException();  int c = ctl.get();//比较核心线程数    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);else if (workerCountOf(recheck) == 0)addWorker(null, false);}//如果添加失败则拒绝else if (!addWorker(command, false))reject(command);}

2.3.1 execute方法相关属性

    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));private static final int COUNT_BITS = Integer.SIZE - 3;private static final int CAPACITY   = (1 << COUNT_BITS) - 1;// runState is stored in the high-order bitsprivate static final int RUNNING    = -1 << COUNT_BITS;private static final int SHUTDOWN   =  0 << COUNT_BITS;private static final int STOP       =  1 << COUNT_BITS;private static final int TIDYING    =  2 << COUNT_BITS;private static final int TERMINATED =  3 << COUNT_BITS;// Packing and unpacking ctlprivate static int runStateOf(int c)     {return c & ~CAPACITY; }private static int workerCountOf(int c)  { return c & CAPACITY; }private static int ctlOf(int rs, int wc) {return rs | wc;}

2.3.2 addWorker方法

private boolean addWorker(Runnable firstTask, boolean core) {retry:for (;;) {int c = ctl.get();int rs = runStateOf(c);// Check if queue empty only if necessary.if (rs >= SHUTDOWN &&! (rs == SHUTDOWN &&firstTask == null &&! workQueue.isEmpty()))return false;for (;;) {int wc = workerCountOf(c);if (wc >= CAPACITY ||wc >= (core ? corePoolSize : maximumPoolSize))return false;if (compareAndIncrementWorkerCount(c))break retry;c = ctl.get();  // Re-read ctlif (runStateOf(c) != rs)continue retry;// else CAS failed due to workerCount change; retry inner loop}}boolean workerStarted = false;boolean workerAdded = false;Worker w = null;try {w = new Worker(firstTask);final Thread t = w.thread;if (t != null) {final ReentrantLock mainLock = this.mainLock;mainLock.lock();try {// Recheck while holding lock.// Back out on ThreadFactory failure or if// shut down before lock acquired.int rs = runStateOf(ctl.get());if (rs < SHUTDOWN ||(rs == SHUTDOWN && firstTask == null)) {if (t.isAlive()) // precheck that t is startablethrow new IllegalThreadStateException();workers.add(w);int s = workers.size();if (s > largestPoolSize)largestPoolSize = s;workerAdded = true;}} finally {mainLock.unlock();}if (workerAdded) {t.start();workerStarted = true;}}} finally {if (! workerStarted)addWorkerFailed(w);}return workerStarted;}

3. ExecutorService

3.1 结构如下

3.2源码如下

public interface ExecutorService extends Executor {//关闭void shutdown();//停止所有正在执行的任务List<Runnable> shutdownNow();  //判断是否关闭boolean isShutdown();//如果关闭后所有任务都已完成,则为 trueboolean isTerminated();  //阻塞直到所有任务在关闭请求后完成执行boolean awaitTermination(long timeout, TimeUnit unit)throws InterruptedException;<T> Future<T> submit(Callable<T> task);<T> Future<T> submit(Runnable task, T result);Future<?> submit(Runnable task);<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)throws InterruptedException;<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit)throws InterruptedException; <T> T invokeAny(Collection<? extends Callable<T>> tasks)throws InterruptedException, ExecutionException;<T> T invokeAny(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException;
}

3.3 submit方法

使用RunnableFuture封装扩展了execute方法接收Callable类型参数。

3.4 关闭线程池



调用shutdown方法之后,线程池将不再接口新任务,内部会将所有已提交的任务处理完毕,处理完毕之后,工作线程自动退出。

而调用shutdownNow方法后,线程池会将还未处理的(在队里等待处理的任务)任务移除,将正在处理中的处理完毕之后,工作线程自动退出。

3.5 判断

isShutdown和isTerminated继承ExecutorService,isTerminating是线程池原生方法,搜索调用发现源码中没有方法调用它。

3.5.1 isShutdown和 isTerminated

3.5.2 awaitTermination

3.6 invoke 调用

批量处理任务,Any和All的区别是有一个任务返回和全部任务返回结果。

    public <T> T invokeAny(Collection<? extends Callable<T>> tasks)throws InterruptedException, ExecutionException {try {return doInvokeAny(tasks, false, 0);} catch (TimeoutException cannotHappen) {assert false;return null;}}public <T> T invokeAny(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException {return doInvokeAny(tasks, true, unit.toNanos(timeout));}public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)throws InterruptedException {//if (tasks == null)throw new NullPointerException();//ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());//boolean done = false;//try {for (Callable<T> t : tasks) {RunnableFuture<T> f = newTaskFor(t);futures.add(f);execute(f);}for (int i = 0, size = futures.size(); i < size; i++) {Future<T> f = futures.get(i);if (!f.isDone()) {try {f.get();} catch (CancellationException ignore) {} catch (ExecutionException ignore) {}}}done = true;return futures;} finally {if (!done)for (int i = 0, size = futures.size(); i < size; i++)futures.get(i).cancel(true);}}public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit)throws InterruptedException {if (tasks == null)throw new NullPointerException();long nanos = unit.toNanos(timeout);ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());boolean done = false;try {for (Callable<T> t : tasks)futures.add(newTaskFor(t));final long deadline = System.nanoTime() + nanos;final int size = futures.size();// Interleave time checks and calls to execute in case// executor doesn't have any/much parallelism.for (int i = 0; i < size; i++) {execute((Runnable)futures.get(i));nanos = deadline - System.nanoTime();if (nanos <= 0L)return futures;}for (int i = 0; i < size; i++) {Future<T> f = futures.get(i);if (!f.isDone()) {if (nanos <= 0L)return futures;try {f.get(nanos, TimeUnit.NANOSECONDS);} catch (CancellationException ignore) {} catch (ExecutionException ignore) {} catch (TimeoutException toe) {return futures;}nanos = deadline - System.nanoTime();}}done = true;return futures;} finally {if (!done)for (int i = 0, size = futures.size(); i < size; i++)futures.get(i).cancel(true);}}

4. AbstractExecutorService

提供 ExecutorService 部分方法的默认实现和其他需求的扩充。

4.1 结构图如下

4.2 类中方法

4.2.1 submit方法

submit相关实现如下


RunnableFuture接口

4.2.2 doInvokeAny方法

invokeAny 方法实现的主要逻辑封装

private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,boolean timed, long nanos)throws InterruptedException, ExecutionException, TimeoutException {if (tasks == null)throw new NullPointerException();int ntasks = tasks.size();if (ntasks == 0)throw new IllegalArgumentException();ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks);ExecutorCompletionService<T> ecs =new ExecutorCompletionService<T>(this);try {// Record exceptions so that if we fail to obtain any// result, we can throw the last exception we got.ExecutionException ee = null;final long deadline = timed ? System.nanoTime() + nanos : 0L;Iterator<? extends Callable<T>> it = tasks.iterator();// Start one task for sure; the rest incrementallyfutures.add(ecs.submit(it.next()));--ntasks;int active = 1;for (;;) {Future<T> f = ecs.poll();if (f == null) {if (ntasks > 0) {--ntasks;futures.add(ecs.submit(it.next()));++active;}else if (active == 0)break;else if (timed) {f = ecs.poll(nanos, TimeUnit.NANOSECONDS);if (f == null)throw new TimeoutException();nanos = deadline - System.nanoTime();}elsef = ecs.take();}if (f != null) {--active;try {return f.get();} catch (ExecutionException eex) {ee = eex;} catch (RuntimeException rex) {ee = new ExecutionException(rex);}}}if (ee == null)ee = new ExecutionException();throw ee;} finally {for (int i = 0, size = futures.size(); i < size; i++)futures.get(i).cancel(true);}}

4.2.3 newTaskFor方法

将Runnable和Callable封装为RunnableFuture类型返回。

5 ThreadPoolExecutor的内部类

5.1 Worker

private final class Workerextends AbstractQueuedSynchronizerimplements Runnable{private static final long serialVersionUID = 6138294804551838833L;/** Thread this worker is running in.  Null if factory fails. */final Thread thread;/** Initial task to run.  Possibly null. */Runnable firstTask;/** Per-thread task counter */volatile long completedTasks;/*** Creates with given first task and thread from ThreadFactory.* @param firstTask the first task (null if none)*/Worker(Runnable firstTask) {setState(-1); // inhibit interrupts until runWorkerthis.firstTask = firstTask;this.thread = getThreadFactory().newThread(this);}/** Delegates main run loop to outer runWorker  */public void run() {runWorker(this);}// Lock methods//// The value 0 represents the unlocked state.// The value 1 represents the locked state.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;}public void lock()        { acquire(1); }public boolean tryLock()  { return tryAcquire(1); }public void unlock()      { release(1); }public boolean isLocked() { return isHeldExclusively(); }void interruptIfStarted() {Thread t;if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {try {t.interrupt();} catch (SecurityException ignore) {}}}}

5.2 策略内部类

5.2.1 AbortPolicy

直接抛出异常 RejectedExecutionException

5.2.2 CallerRunsPolicy

线程池关闭丢弃任务,没有关闭交给当前线程执行任务。

5.2.3 DiscardOldestPolicy

线程池关闭直接丢弃,线程池没有关闭获取队列并移除头部元素,执行任务。

5.2.4 DiscardPolicy

什么都不做,相当于丢弃任务r。

6. ThreadPoolExecutor的属性

6.1 结构图

6.2 源码如下

    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));private static final int COUNT_BITS = Integer.SIZE - 3;private static final int CAPACITY   = (1 << COUNT_BITS) - 1;// runState is stored in the high-order bitsprivate static final int RUNNING    = -1 << COUNT_BITS;private static final int SHUTDOWN   =  0 << COUNT_BITS;private static final int STOP       =  1 << COUNT_BITS;private static final int TIDYING    =  2 << COUNT_BITS;private static final int TERMINATED =  3 << COUNT_BITS;private final BlockingQueue<Runnable> workQueue;private final ReentrantLock mainLock = new ReentrantLock();private final HashSet<Worker> workers = new HashSet<Worker>();private final Condition termination = mainLock.newCondition();private int largestPoolSize;private long completedTaskCount;private volatile ThreadFactory threadFactory;private volatile RejectedExecutionHandler handler;private volatile long keepAliveTime;private volatile boolean allowCoreThreadTimeOut;private volatile int corePoolSize;private volatile int maximumPoolSize;private static final RejectedExecutionHandler defaultHandler =new AbortPolicy();private static final RuntimePermission shutdownPerm =new RuntimePermission("modifyThread");private final AccessControlContext acc;private static final boolean ONLY_ONE = true;

6.3 属性解析

7.ThreadPoolExecutor 构造函数

7.1 五个参数构造函数

使用默认线程工厂和默认处理策略。

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

7.2 默认策略构造函数

使用了默认的handler

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


7.3 默认线程工厂构造函数

六个参数的构造函数,使用了默认的线程工厂Executors.defaultThreadFactory()

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

7.4 完全参数构造函数

 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();//acc赋值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;}

acc参数的使用



acc参数一共出现了四次,其中第一次是定义,第二次是构造函数赋值,其余出现在finalize方法中

不过finalize方法并没有被其他方法调用,所以acc的用处还未知。

7.5 合理地配置线程池

7.5.1 cpu密集

CPU密集型任务应该尽可能小的线程,如配置cpu数量+1个线程的线程池。

7.5.2 io密集

由于IO密集型任务并不是一直在执行任务,不能让cpu闲着,则应配置尽可能多的线程,如:cup数量*2。

7.5.3 队列

使用队列的时候建议使用有界队列,有界队列增加了系统的稳定性,如果采用无界队列,任务太多的时候可能导致系统OOM,直接让系统宕机。

8. ThreadPoolExecutor 方法

8.1 public方法

8.1.1 allowCoreThreadTimeOut

8.1.2 allowsCoreThreadTimeOut


调用发生在setKeepAliveTime方法

8.1.3 getKeepAliveTime

本类中无调用

8.1.4 prestartAllCoreThreads

本类无调用

8.1.5 prestartCoreThread

8.1.6 purge

未发现该方法调用

8.1.7 remove

移除任务,执行tryTerminate()方法。方法调用发生在execute方法

8.1.8 setKeepAliveTime

本类无调用

8.2 protected方法

8.2.1 afterExecute

任务执行之后调用的方法

8.2.2 beforeExecute

任务执行之前调用的方法

8.2.3 terminated


tryTerminate 方法中的调用

8.3 无修饰符方法

8.3.1 ensurePrestart

本类无调用

8.3.2 isRunningOrShutdown

本类无调用

8.3.3 onShutdown


调用位置shutdown方法

8.3.4 reject

拒绝任务,调用发生在execute方法中,

8.3.5 runWorker

final void runWorker(Worker w) {Thread wt = Thread.currentThread();Runnable task = w.firstTask;w.firstTask = null;w.unlock(); // allow interruptsboolean completedAbruptly = true;try {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 interruptif ((runStateAtLeast(ctl.get(), STOP) ||(Thread.interrupted() &&runStateAtLeast(ctl.get(), STOP))) &&!wt.isInterrupted())wt.interrupt();try {beforeExecute(wt, task);Throwable thrown = null;try {task.run();} catch (RuntimeException x) {thrown = x; throw x;} catch (Error x) {thrown = x; throw x;} catch (Throwable x) {thrown = x; throw new Error(x);} finally {afterExecute(task, thrown);}} finally {task = null;w.completedTasks++;w.unlock();}}completedAbruptly = false;} finally {processWorkerExit(w, completedAbruptly);}}

调用发生在内部类Worke中

8.3.6 tryTerminate

final void tryTerminate() {for (;;) {int c = ctl.get();if (isRunning(c) ||runStateAtLeast(c, TIDYING) ||(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))return;if (workerCountOf(c) != 0) { // Eligible to terminateinterruptIdleWorkers(ONLY_ONE);return;}final ReentrantLock mainLock = this.mainLock;mainLock.lock();try {if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {try {terminated();} finally {ctl.set(ctlOf(TERMINATED, 0));termination.signalAll();}return;}} finally {mainLock.unlock();}// else retry on failed CAS}}

调用位置





8.4 private方法

8.4.1 addWorker

private boolean addWorker(Runnable firstTask, boolean core) {retry:for (;;) {int c = ctl.get();int rs = runStateOf(c);// Check if queue empty only if necessary.if (rs >= SHUTDOWN &&! (rs == SHUTDOWN &&firstTask == null &&! workQueue.isEmpty()))return false;for (;;) {int wc = workerCountOf(c);if (wc >= CAPACITY ||wc >= (core ? corePoolSize : maximumPoolSize))return false;if (compareAndIncrementWorkerCount(c))break retry;c = ctl.get();  // Re-read ctlif (runStateOf(c) != rs)continue retry;// else CAS failed due to workerCount change; retry inner loop}}boolean workerStarted = false;boolean workerAdded = false;Worker w = null;try {w = new Worker(firstTask);final Thread t = w.thread;if (t != null) {final ReentrantLock mainLock = this.mainLock;mainLock.lock();try {// Recheck while holding lock.// Back out on ThreadFactory failure or if// shut down before lock acquired.int rs = runStateOf(ctl.get());if (rs < SHUTDOWN ||(rs == SHUTDOWN && firstTask == null)) {if (t.isAlive()) // precheck that t is startablethrow new IllegalThreadStateException();workers.add(w);int s = workers.size();if (s > largestPoolSize)largestPoolSize = s;workerAdded = true;}} finally {mainLock.unlock();}if (workerAdded) {t.start();workerStarted = true;}}} finally {if (! workerStarted)addWorkerFailed(w);}return workerStarted;}

8.4.2 addWorkerFailed


调用发生在 addWorker

8.4.3 advanceRunState


调用关系

8.4.4 checkShutdownAccess


调用关系 shutdown和shutdownnow方法

8.4.5 compareAndDecrementWorkerCount

8.4.6 compareAndIncrementWorkerCount

8.4.7 ctlOf

private static int ctlOf(int rs, int wc) { return rs | wc; }

8.4.8 decrementWorkerCount

8.4.9 drainQueue

8.4.10 interruptIdleWorkers

8.4.11 interruptIdleWorkers

8.4.12 interruptWorkers

8.4.13 isRunning

8.4.14 processWorkerExit

8.4.15 runStateAtLeast

8.4.16 runStateLessThan

8.4.16 runStateOf

    private static int workerCountOf(int c) {return c & ~CAPACITY;}

8.4.17 workerCountOf

    private static int workerCountOf(int c) {return c & CAPACITY;}

9 常见问题

9.1 submit和execute方法有什么区别

void execute(Runnable command);

submit方法

  1. 区别1 来源接口不同,execute来源Executor接口,而submit来源ExecutorService接口。
  2. 区别2 返回值不同 execute返回void,而submit返回Future对象。
  3. 区别3 入参不同 execute接收Runnable接口,submit还支持Callable接口。
  4. 区别4 异常抛出 execute当前线程遇到异常直接抛出,而submit在主线程调用get方法时才会抛出ExecutionException异常。

    FutureTask 中get方法如图所示

    FutureTask 中report方法如图所示

9.2 newFixedThreadPool



创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,在提交新任务,任务将会进入等待队列中等待。如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。内部使用了无限容量的LinkedBlockingQueue阻塞队列来缓存任务,任务如果比较多,如果处理不过来,会导致队列堆满,引发OOM。

9.3 newCachedThreadPool


创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,

那么就会回收部分空闲(60秒处于等待任务到来)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池的最大值是Integer的最大值(2^31-1)。内部使用了SynchronousQueue同步队列来缓存任务,此队列的特性是放入任务时必须要有对应的线程获取任务,任务才可以放入成功。如果处理的任务比较耗时,任务来的速度也比较快,会创建太多的线程引发OOM。

9.4 newSingleThreadExecutor


创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。内部使用了无限容量的LinkedBlockingQueue阻塞队列来缓存任务,任务如果比较多,单线程如果处理不过来,会导致队列堆满,引发OOM。

9.5 线程池中队列的使用

//定义存放Runnable类型队列
private final BlockingQueue<Runnable> workQueue;
//判断是否为空
workQueue.isEmpty()
//
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
Runnable r = timed ? workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : workQueue.take();
//类同 add 不过不会抛异常
workQueue.offer(command)
//获取队列大小
workQueue.size()
//移出元素
workQueue.remove(task)

9.6 异步线程执行失败怎么办

问题描述:如何保证主线程和异步线程的原子性,即不允许一个失败一个成功。
以一个主线程和一个子线程为例,有两种特殊情况,主失败和子失败。
类比分布式事务。

9.7 为什么先添加队列后创建线程

最大线程数其实是为了应付突发状况。举个装修的例子,正常情况下施工队只要 3 个人去干活,这 3 人其实就是核心线程,但是由于工头接的活太多了,导致 3 个人在约定工期内干不完,所以工头又去找了 2 个人来一起干,所以 3 是核心线程数,5 是最大线程数。平时就是 3 个人干活,特别忙的时候就找 5 个,等闲下来就会把多余的 2 个辞了。

名词简称

corePoolSize 核心池大小
maximumPoolSize 最大池大小
keepAliveTime 存活时间
workQueue 队列
threadFactory 工厂
handler 处理

深入浅出java并发编程(线程池)相关推荐

  1. Java 并发编程 -- 线程池源码实战

    一.概述 小编在网上看了好多的关于线程池原理.源码分析相关的文章,但是说实话,没有一篇让我觉得读完之后豁然开朗,完完全全的明白线程池,要么写的太简单,只写了一点皮毛,要么就是是晦涩难懂,看完之后几乎都 ...

  2. Java并发编程——线程池的使用

    在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统 ...

  3. java workerdone_【架构】Java并发编程——线程池的使用

    前言 如果我们要使用线程的时候就去创建一个,这样虽然非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为 ...

  4. Java并发编程——线程池初步

    概述: 线程池机制是事先创建一些线程等待服务端程序的调用,这些线程保存在一个数组结构中,称为"线程池".当服务器有任务执行时,就从线程池中取出一个线程并给其分配任务,当线程任务执行 ...

  5. java并发编程——线程池的工作原理与源码解读

    2019独角兽企业重金招聘Python工程师标准>>> 线程池的简单介绍 基于多核CPU的发展,使得多线程开发日趋流行.然而线程的创建和销毁,都涉及到系统调用,比较消耗系统资源,所以 ...

  6. Java并发编程-线程池底层工作原理

    线程池底层工作原理 1.线程池的底层工作流程 1.1.线程池的底层工作原理图 1.2.银行办理业务案例 1.3.线程池的底层工作流程总结 2.线程池用哪个?生产中如何设置合理参数 2.1.在工作中单一 ...

  7. java并发测试 线程池,Java并发编程——线程池

    1.任务与执行策略间的隐性耦合 一些任务具有这样的特征:需要或者排斥某种特定的执行策略.对其他任务具有依赖性的任务,就会要求线程池足够大,来保证它锁依赖任务不必排队或者不被拒绝:采用线程限制的任务需要 ...

  8. java线程池_Java 并发编程 线程池源码实战

    作者 | 马启航 杏仁后端工程师.「我头发还多,你们呢?」 一.概述 笔者在网上看了好多的关于线程池原理.源码分析相关的文章,但是说实话,没有一篇让我觉得读完之后豁然开朗,完完全全的明白线程池,要么写 ...

  9. Java并发编程—线程间协作方式wait()、notify()、notifyAll()和Condition

    原文作者:Matrix海 子 原文地址:Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 目录 一.wait().notify()和notifyA ...

  10. 灵魂发问,Java并发和线程池,只言片语真的可以讲清楚吗?

    线程池 最近看到线程池,被里边乱七八槽的参数给搞晕了,你能不能给我讲讲呀? 对于从事后端开发的同学来说,线程是必须要使用了,因为使用它可以提升系统的性能.但是,创建线程和销毁线程都是比较耗时的操作,频 ...

最新文章

  1. 2021年大数据基础(三):​​​​​​​​​​​​​​​​​​​​​大数据应用场景
  2. orion的简单测试
  3. Xilinx SelectIO 接口
  4. 开启php支持xml,PHP对XML的支持
  5. java定时器返回future_java 定时器线程池(ScheduledThreadPoolExecutor)的实现
  6. hdu 1588 Gauss Fibonacci 较难
  7. 新建springBoot项目提示:The type org.springframework.context.ConfigurableApplicationContext cannot be resol
  8. 洛谷 - P3975 [TJOI2015]弦论(后缀自动机)
  9. Hadoop之Yarn面试知识复习
  10. ESP8266在Alios-Things上的入门开发指南 (一)开发环境搭建及HelloWorld固件
  11. 【WC2014】时空穿梭【组合数】【莫比乌斯反演】【整除分块】【暴力多项式】
  12. 最小函数值(信息学奥赛一本通-T1370)
  13. python做日历牌_中秋节到了,送你一个Python做的Crossin牌“月饼”
  14. 表中存在类型为dateTime的字段,并且插入语句,不包括该字段时,会插入失败...
  15. 万用表测线路断点位置_万用表测电流口诀,正确使用方法
  16. python二维数据读取对齐_[Python ] Python 多维数组转换的维度对齐问题
  17. ardupilot在Linux上设置SITL(FlightGear)
  18. python货币转化为资本的前提_Python与《资本论》:生产资本中劳动力 A 与生产资料 Pm 的配比关系...
  19. 最全最新的的Java核心知识点整理!!! 【推荐】
  20. 7、JSON数据和Java对象的相互转换(客户端和服务器对象数据通讯用)

热门文章

  1. 【滤波】一维卡尔曼滤波器
  2. 51单片机【五】LED点阵屏
  3. SpringBoot中Redis报错:NOAUTH Authentication required.; nested exception is redis.clients.jedis.exceptio
  4. 你不可不知的宇宙简史
  5. 凸集学习——理解凸集概念、凸包演示
  6. Don't Starve,好脚本,好欢乐
  7. 关于电脑网速网占用问题(svchost.exe)(¥72)
  8. 网站端服务器返回错误8001,云服务器 http server
  9. ttf,eot,woff,svg,字体格式介绍及使用方法
  10. IBM新型Tivoli产品搭建绿色销售渠道