前言

多线程的异步执行方式,虽然能够最大限度发挥多核计算机的计算能力,但是如果不加控制,反而会对系统造成负担。线程本身也要占用内存空间,大量的线程会占用内存资源并且可能会导致Out of Memory。即便没有这样的情况,大量的线程回收也会给GC带来很大的压力。

为了避免重复的创建线程,线程池的出现可以让线程进行复用。通俗点讲,当有工作来,就会向线程池拿一个线程,当工作完成后,并不是直接关闭线程,而是将这个线程归还给线程池供其他任务使用。

接下来从总体到细致的方式,来共同探讨线程池。

总体的架构

来看Executor的框架图:

aaarticlea/png;base64,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" alt="" />

接口:Executor,CompletionService,ExecutorService,ScheduledExecutorService

抽象类:AbstractExecutorService

实现类:ExecutorCompletionService,ThreadPoolExecutor,ScheduledThreadPoolExecutor

从图中就可以看到主要的方法,本文主要讨论的是ThreadPoolExecutor

研读ThreadPoolExecutor

看一下该类的构造器:

    public ThreadPoolExecutor(int paramInt1, int paramInt2, long paramLong, TimeUnit paramTimeUnit,
BlockingQueue<Runnable> paramBlockingQueue, ThreadFactory paramThreadFactory,
RejectedExecutionHandler paramRejectedExecutionHandler) {
this.ctl = new AtomicInteger(ctlOf(-536870912, 0));
this.mainLock = new ReentrantLock();
this.workers = new HashSet();
this.termination = this.mainLock.newCondition();
if ((paramInt1 < 0) || (paramInt2 <= 0) || (paramInt2 < paramInt1) || (paramLong < 0L))
throw new IllegalArgumentException();
if ((paramBlockingQueue == null) || (paramThreadFactory == null) || (paramRejectedExecutionHandler == null))
throw new NullPointerException();
this.corePoolSize = paramInt1;
this.maximumPoolSize = paramInt2;
this.workQueue = paramBlockingQueue;
this.keepAliveTime = paramTimeUnit.toNanos(paramLong);
this.threadFactory = paramThreadFactory;
this.handler = paramRejectedExecutionHandler;
}

corePoolSize :线程池的核心池大小,在创建线程池之后,线程池默认没有任何线程。

当有任务过来的时候才会去创建创建线程执行任务。换个说法,线程池创建之后,线程池中的线程数为0,当任务过来就会创建一个线程去执行,直到线程数达到corePoolSize 之后,就会被到达的任务放在队列中。(注意是到达的任务)。换句更精炼的话:corePoolSize 表示允许线程池中允许同时运行的最大线程数。

如果执行了线程池的prestartAllCoreThreads()方法,线程池会提前创建并启动所有核心线程。

maximumPoolSize :线程池允许的最大线程数,他表示最大能创建多少个线程。maximumPoolSize肯定是大于等于corePoolSize。

keepAliveTime :表示线程没有任务时最多保持多久然后停止。默认情况下,只有线程池中线程数大于corePoolSize 时,keepAliveTime 才会起作用。换句话说,当线程池中的线程数大于corePoolSize,并且一个线程空闲时间达到了keepAliveTime,那么就是shutdown。

Unit:keepAliveTime 的单位。

workQueue :一个阻塞队列,用来存储等待执行的任务,当线程池中的线程数超过它的corePoolSize的时候,线程会进入阻塞队列进行阻塞等待。通过workQueue,线程池实现了阻塞功能

threadFactory :线程工厂,用来创建线程。

handler :表示当拒绝处理任务时的策略。

任务缓存队列

在前面我们多次提到了任务缓存队列,即workQueue,它用来存放等待执行的任务。

workQueue的类型为BlockingQueue<Runnable>,通常可以取下面三种类型:

1)有界任务队列ArrayBlockingQueue:基于数组的先进先出队列,此队列创建时必须指定大小;

2)无界任务队列LinkedBlockingQueue:基于链表的先进先出队列,如果创建时没有指定此队列大小,则默认为Integer.MAX_VALUE;

3)直接提交队列synchronousQueue:这个队列比较特殊,它不会保存提交的任务,而是将直接新建一个线程来执行新来的任务。

拒绝策略

AbortPolicy:丢弃任务并抛出RejectedExecutionException

CallerRunsPolicy:只要线程池未关闭,该策略直接在调用者线程中,运行当前被丢弃的任务。显然这样做不会真的丢弃任务,但是,任务提交线程的性能极有可能会急剧下降。

DiscardOldestPolicy:丢弃队列中最老的一个请求,也就是即将被执行的一个任务,并尝试再次提交当前任务。

DiscardPolicy:丢弃任务,不做任何处理。

线程池的任务处理策略:

如果当前线程池中的线程数目小于corePoolSize,则每来一个任务,就会创建一个线程去执行这个任务;

如果当前线程池中的线程数目>=corePoolSize,则每来一个任务,会尝试将其添加到任务缓存队列当中,若添加成功,则该任务会等待空闲线程将其取出去执行;若添加失败(一般来说是任务缓存队列已满),则会尝试创建新的线程去执行这个任务;如果当前线程池中的线程数目达到maximumPoolSize,则会采取任务拒绝策略进行处理;

如果线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止,直至线程池中的线程数目不大于corePoolSize;如果允许为核心池中的线程设置存活时间,那么核心池中的线程空闲时间超过keepAliveTime,线程也会被终止。

线程池的关闭

ThreadPoolExecutor提供了两个方法,用于线程池的关闭,分别是shutdown()和shutdownNow(),其中:

shutdown():不会立即终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务

shutdownNow():立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务

源码分析

首先来看最核心的execute方法,这个方法在AbstractExecutorService中并没有实现,从Executor接口,直到ThreadPoolExecutor才实现了改方法,

ExecutorService中的submit(),invokeAll(),invokeAny()都是调用的execute方法,所以execute是核心中的核心,源码分析将围绕它逐步展开。

    public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
/*
* Proceed in 3 steps:
*
* 1. If fewer than corePoolSize threads are running, try to
* start a new thread with the given command as its first
* task. The call to addWorker atomically checks runState and
* workerCount, and so prevents false alarms that would add
* threads when it shouldn't, by returning false.
* 如果正在运行的线程数小于corePoolSize,那么将调用addWorker 方法来创建一个新的线程,并将该任务作为新线程的第一个任务来执行。
       当然,在创建线程之前会做原子性质的检查,如果条件不允许,则不创建线程来执行任务,并返回false.  
* 2. If a task can be successfully queued, then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* recheck state and if necessary roll back the enqueuing if
* stopped, or start a new thread if there are none.
* 如果一个任务成功进入阻塞队列,那么我们需要进行一个双重检查来确保是我们已经添加一个线程(因为存在着一些线程在上次检查后他已经死亡)或者
       当我们进入该方法时,该线程池已经关闭。所以,我们将重新检查状态,线程池关闭的情况下则回滚入队列,线程池没有线程的情况则创建一个新的线程。
* 3. If we cannot queue task, then we try to add a new
* thread. If it fails, we know we are shut down or saturated
* and so reject the task.
       如果任务无法入队列(队列满了),那么我们将尝试新开启一个线程(从corepoolsize到扩充到maximum),如果失败了,那么可以确定原因,要么是
       线程池关闭了或者饱和了(达到maximum),所以我们执行拒绝策略。
*/
    
    // 1.当前线程数量小于corePoolSize,则创建并启动线程。
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
        // 成功,则返回
return;
c = ctl.get();
}
    // 2.步骤1失败,则尝试进入阻塞队列,
if (isRunning(c) && workQueue.offer(command)) {
       // 入队列成功,检查线程池状态,如果状态部署RUNNING而且remove成功,则拒绝任务
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
       // 如果当前worker数量为0,通过addWorker(null, false)创建一个线程,其任务为null
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
    // 3. 步骤1和2失败,则尝试将线程池的数量有corePoolSize扩充至maxPoolSize,如果失败,则拒绝任务
else if (!addWorker(command, false))
reject(command);
}

相信看了代码也是一脸懵,接下来用一个流程图来讲一讲,他究竟干了什么事:

结合上面的流程图来逐行解析,首先前面进行空指针检查,

wonrkerCountOf()方法能够取得当前线程池中的线程的总数,取得当前线程数与核心池大小比较,

  • 如果小于,将通过addWorker()方法调度执行。
  • 如果大于核心池大小,那么就提交到等待队列。
  • 如果进入等待队列失败,则会将任务直接提交给线程池。
  • 如果线程数达到最大线程数,那么就提交失败,执行拒绝策略。

excute()方法中添加任务的方式是使用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;
       // 内层的循环,任务是将worker数量加1
for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
if (compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get(); // Re-read ctl
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
    // worker加1后,接下来将woker添加到HashSet<Worker>中,并启动worker
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
final ReentrantLock mainLock = this.mainLock;
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
mainLock.lock();
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int c = ctl.get();
int rs = runStateOf(c); if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
         // 如果往HashSet<Worker>添加成功,则启动该线程
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}

addWorker(Runnable firstTask, boolean core)的主要任务是创建并启动线程。

他会根据当前线程的状态和给定的值(core or maximum)来判断是否可以创建一个线程。

addWorker共有四种传参方式。execute使用了其中三种,分别为:

1.addWorker(paramRunnable, true)

线程数小于corePoolSize时,放一个需要处理的task进Workers Set。如果Workers Set长度超过corePoolSize,就返回false.

2.addWorker(null, false)

放入一个空的task进workers Set,长度限制是maximumPoolSize。这样一个task为空的worker在线程执行的时候会去任务队列里拿任务,这样就相当于创建了一个新的线程,只是没有马上分配任务。

3.addWorker(paramRunnable, false)

当队列被放满时,就尝试将这个新来的task直接放入Workers Set,而此时Workers Set的长度限制是maximumPoolSize。如果线程池也满了的话就返回false.

还有一种情况是execute()方法没有使用的

addWorker(null, true)

这个方法就是放一个null的task进Workers Set,而且是在小于corePoolSize时,如果此时Set中的数量已经达到corePoolSize那就返回false,什么也不干。实际使用中是在prestartAllCoreThreads()方法,这个方法用来为线程池预先启动corePoolSize个worker等待从workQueue中获取任务执行。

执行流程:

1、判断线程池当前是否为可以添加worker线程的状态,可以则继续下一步,不可以return false:
    A、线程池状态>shutdown,可能为stop、tidying、terminated,不能添加worker线程
    B、线程池状态==shutdown,firstTask不为空,不能添加worker线程,因为shutdown状态的线程池不接收新任务
    C、线程池状态==shutdown,firstTask==null,workQueue为空,不能添加worker线程,因为firstTask为空是为了添加一个没有任务的线程再从workQueue获取task,而workQueue为      空,说明添加无任务线程已经没有意义
2、线程池当前线程数量是否超过上限(corePoolSize 或 maximumPoolSize),超过了return false,没超过则对workerCount+1,继续下一步
3、在线程池的ReentrantLock保证下,向Workers Set中添加新创建的worker实例,添加完成后解锁,并启动worker线程,如果这一切都成功了,return true,如果添加worker入Set失败或启动失败,调用addWorkerFailed()逻辑

常见的四种线程池

newFixedThreadPool

public static ExecutorService newFixedThreadPool(int var0) {
return new ThreadPoolExecutor(var0, var0, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
}
public static ExecutorService newFixedThreadPool(int var0, ThreadFactory var1) {
return new ThreadPoolExecutor(var0, var0, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), var1);
}

固定大小的线程池,可以指定线程池的大小,该线程池corePoolSize和maximumPoolSize相等,阻塞队列使用的是LinkedBlockingQueue,大小为整数最大值。

该线程池中的线程数量始终不变,当有新任务提交时,线程池中有空闲线程则会立即执行,如果没有,则会暂存到阻塞队列。对于固定大小的线程池,不存在线程数量的变化。同时使用无界的LinkedBlockingQueue来存放执行的任务。当任务提交十分频繁的时候,LinkedBlockingQueue

迅速增大,存在着耗尽系统资源的问题。而且在线程池空闲时,即线程池中没有可运行任务时,它也不会释放工作线程,还会占用一定的系统资源,需要shutdown。

newSingleThreadExecutor

public static ExecutorService newSingleThreadExecutor() {
return new Executors.FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()));
} public static ExecutorService newSingleThreadExecutor(ThreadFactory var0) {
return new Executors.FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), var0));
}

单个线程线程池,只有一个线程的线程池,阻塞队列使用的是LinkedBlockingQueue,若有多余的任务提交到线程池中,则会被暂存到阻塞队列,待空闲时再去执行。按照先入先出的顺序执行任务。

newCachedThreadPool

public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, 2147483647, 60L, TimeUnit.SECONDS, new SynchronousQueue());
} public static ExecutorService newCachedThreadPool(ThreadFactory var0) {
return new ThreadPoolExecutor(0, 2147483647, 60L, TimeUnit.SECONDS, new SynchronousQueue(), var0);
}

缓存线程池,缓存的线程默认存活60秒。线程的核心池corePoolSize大小为0,核心池最大为Integer.MAX_VALUE,阻塞队列使用的是SynchronousQueue。是一个直接提交的阻塞队列,    他总会迫使线程池增加新的线程去执行新的任务。在没有任务执行时,当线程的空闲时间超过keepAliveTime(60秒),则工作线程将会终止被回收,当提交新任务时,如果没有空闲线程,则创建新线程执行任务,会导致一定的系统开销。如果同时又大量任务被提交,而且任务执行的时间不是特别快,那么线程池便会新增出等量的线程池处理任务,这很可能会很快耗尽系统的资源。

newScheduledThreadPool

public static ScheduledExecutorService newScheduledThreadPool(int var0) {
return new ScheduledThreadPoolExecutor(var0);
} public static ScheduledExecutorService newScheduledThreadPool(int var0, ThreadFactory var1) {
return new ScheduledThreadPoolExecutor(var0, var1);
}

定时线程池,该线程池可用于周期性地去执行任务,通常用于周期性的同步数据。

scheduleAtFixedRate:是以固定的频率去执行任务,周期是指每次执行任务成功执行之间的间隔。

schedultWithFixedDelay:是以固定的延时去执行任务,延时是指上一次执行成功之后和下一次开始执行的之前的时间。

使用实例

newFixedThreadPool实例:

 

newCachedThreadPool实例:

 

这里没用调用shutDown方法,这里可以发现过60秒之后,会自动释放资源。

newSingleThreadExecutor

 

这里需要注意一点,newSingleThreadExecutor和newFixedThreadPool一样,在线程池中没有任务时可执行,也不会释放系统资源的,所以需要shudown。

newScheduledThreadPool

 

最后杂谈

如何选择线程池数量

线程池的大小决定着系统的性能,过大或者过小的线程池数量都无法发挥最优的系统性能。

当然线程池的大小也不需要做的太过于精确,只需要避免过大和过小的情况。一般来说,确定线程池的大小需要考虑CPU的数量,内存大小,任务是计算密集型还是IO密集型等因素

NCPU = CPU的数量

UCPU = 期望对CPU的使用率 0 ≤ UCPU ≤ 1

W/C = 等待时间与计算时间的比率

如果希望处理器达到理想的使用率,那么线程池的最优大小为:

线程池大小=NCPU *UCPU(1+W/C)

在Java中使用

int ncpus = Runtime.getRuntime().availableProcessors();

获取CPU的数量。

线程池工厂

Executors的线程池如果不指定线程工厂会使用Executors中的DefaultThreadFactory,默认线程池工厂创建的线程都是非守护线程。

使用自定义的线程工厂可以做很多事情,比如可以跟踪线程池在何时创建了多少线程,也可以自定义线程名称和优先级。如果将

新建的线程都设置成守护线程,当主线程退出后,将会强制销毁线程池。

下面这个例子,记录了线程的创建,并将所有的线程设置成守护线程。

 

扩展线程池

ThreadPoolExecutor是可以拓展的,它提供了几个可以在子类中改写的方法:beforeExecute,afterExecute和terimated。

在执行任务的线程中将调用beforeExecute和afterExecute,这些方法中还可以添加日志,计时,监视或统计收集的功能,

还可以用来输出有用的调试信息,帮助系统诊断故障。下面是一个扩展线程池的例子:

 

线程池的正确使用

以下阿里编码规范里面说的一段话:

线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。 说明:Executors各个方法的弊端:
1)newFixedThreadPool和newSingleThreadExecutor:
  主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至OOM。
2)newCachedThreadPool和newScheduledThreadPool:
  主要问题是线程数最大数是Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至OOM。

手动创建线程池有几个注意点

1.任务独立。如何任务依赖于其他任务,那么可能产生死锁。例如某个任务等待另一个任务的返回值或执行结果,那么除非线程池足够大,否则将发生线程饥饿死锁。

2.合理配置阻塞时间过长的任务。如果任务阻塞时间过长,那么即使不出现死锁,线程池的性能也会变得很糟糕。在Java并发包里可阻塞方法都同时定义了限时方式和不限时方式。例如

Thread.join,BlockingQueue.put,CountDownLatch.await等,如果任务超时,则标识任务失败,然后中止任务或者将任务放回队列以便随后执行,这样,无论任务的最终结果是否成功,这种办法都能够保证任务总能继续执行下去。

3.设置合理的线程池大小。只需要避免过大或者过小的情况即可,上文的公式线程池大小=NCPU *UCPU(1+W/C)

4.选择合适的阻塞队列。newFixedThreadPool和newSingleThreadExecutor都使用了无界的阻塞队列,无界阻塞队列会有消耗很大的内存,如果使用了有界阻塞队列,它会规避内存占用过大的问题,但是当任务填满有界阻塞队列,新的任务该怎么办?在使用有界队列是,需要选择合适的拒绝策略,队列的大小和线程池的大小必须一起调节。对于非常大的或者无界的线程池,可以使用SynchronousQueue来避免任务排队,以直接将任务从生产者提交到工作者线程。

下面是Thrift框架处理socket任务所使用的一个线程池,可以看一下FaceBook的工程师是如何自定义线程池的。

    private static ExecutorService createDefaultExecutorService(Args args) {
SynchronousQueue executorQueue = new SynchronousQueue(); return new ThreadPoolExecutor(args.minWorkerThreads, args.maxWorkerThreads, 60L, TimeUnit.SECONDS,
executorQueue);
}
TEST
新建线程池:
protected ExecutorService testThreadPool = Executors.newFixedThreadPool(5);
   Map<String, String> scoreTestMap = new HashMap<String, String>();
   TestCallable testCallable = new TestCallable(testService, words, clusRedisTemplate);
FutureTask<Map<String,String>> futureTestTask = new FutureTask<Map<String,String>>(testCallable);
testThreadPool .submit(futureTestTask);
scoreTestMap = futureTestTask.get(200, TimeUnit.MILLISECONDS);
 

总结:

查看以备份

参考资料

《实战Java》高并发程序设计

《Java Concurrency in Practice》

Java线程池ThreadPoolExecutor使用和分析(二)

https://www.jb51.net/article/121296.htm

https://blog.csdn.net/u011277123/article/details/78257336

多线程使用场景:

  1. 常见的浏览器、Web服务(现在写的web是中间件帮你完成了线程的控制),web处理请求,各种专用服务器(如游戏服务器)
  2. servlet多线程
  3. FTP下载,多线程操作文件
  4. 数据库用到的多线程
  5. 分布式计算
  6. tomcat,tomcat内部采用多线程,上百个客户端访问同一个WEB应用,tomcat接入后就是把后续的处理扔给一个新的线程来处理,这个新的线程最后调用我们的servlet程序,比如doGet或者dpPost方法
  7. 后台任务:如定时向大量(100W以上)的用户发送邮件;定期更新配置文件、任务调度(如quartz),一些监控用于定期信息采集
  8. 自动作业处理:比如定期备份日志、定期备份数据库
  9. 异步处理:如发微博、记录日志
  10. 页面异步处理:比如大批量数据的核对工作(有10万个手机号码,核对哪些是已有用户)
  11. 数据库的数据分析(待分析的数据太多),数据迁移
  12. 多步骤的任务处理,可根据步骤特征选用不同个数和特征的线程来协作处理,多任务的分割,由一个主线程分割给多个线程完成
  13. desktop应用开发,一个费时的计算开个线程,前台加个进度条显示
  14. swing编程

Java线程池理解及用法的更多相关文章

  1. 四种Java线程池用法解析

    本文为大家分析四种Java线程池用法,供大家参考,具体内容如下 http://www.jb51.net/article/81843.htm 1.new Thread的弊端 执行一个异步任务你还只是如下 ...

  2. 深入理解Java线程池:ScheduledThreadPoolExecutor

    介绍 自JDK1.5开始,JDK提供了ScheduledThreadPoolExecutor类来支持周期性任务的调度.在这之前的实现需要依靠Timer和TimerTask或者其它第三方工具来完成.但T ...

  3. 干货,阿里P8浅谈对java线程池的理解(面试必备)

    线程池的概念 线程池由任务队列和工作线程组成,它可以重用线程来避免线程创建的开销,在任务过多时通过排队避免创建过多线程来减少系统资源消耗和竞争,确保任务有序完成:ThreadPoolExecutor ...

  4. 深入理解 Java 线程池

    一.简介 什么是线程池 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务. 为什么要用线程池 如果并发请求数量很多,但每个线程执行的时间很短,就会出现频繁的创建 ...

  5. 由浅入深理解Java线程池及线程池的如何使用

    前言 多线程的异步执行方式,虽然能够最大限度发挥多核计算机的计算能力,但是如果不加控制,反而会对系统造成负担.线程本身也要占用内存空间,大量的线程会占用内存资源并且可能会导致Out of Memory ...

  6. 面试题:四种Java线程池用法解析 !=!=未看

    1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? 1 2 3 4 5 6 7 8 new Thread(new Runnable() {     @Override ...

  7. Java并发指南12:深度解读 java 线程池设计思想及源码实现

    ​深度解读 java 线程池设计思想及源码实现 转自 https://javadoop.com/2017/09/05/java-thread-pool/hmsr=toutiao.io&utm_ ...

  8. Java线程池使用说明

    Java线程池使用说明 转自:http://blog.csdn.net/sd0902/article/details/8395677 一简介 线程的使用在java中占有极其重要的地位,在jdk1.4极 ...

  9. Java线程池的那些事

    熟悉java多线程的朋友一定十分了解java的线程池,jdk中的核心实现类为java.util.concurrent.ThreadPoolExecutor.大家可能了解到它的原理,甚至看过它的源码:但 ...

随机推荐

  1. eureka 和zookeeper 区别 优势【转】

    作为服务注册中心,Eureka比Zookeeper好在哪里 著名的CAP理论指出,一个分布式系统不可能同时满足C(一致性).A(可用性)和P(分区容错性).由于分区容错性在是分布式系统中必须要保证的, ...

  2. 获取指定tag的代码

    git checkout v1.0.3 再使用ls查看就可以了

  3. Qt532.QString_填充字符

    1.代码: void MainWindow::on_pushButton_clicked() { QString str = "; QString str01 = str.leftJusti ...

  4. try....fail....catch...Assert 模式的测试, fail是Junit中的功能

    try { // 反射读取properties文件 new BufferedReader(new FileReader(myConfigPath[4])); //上面没有抛出异常就是执行fail, / ...

  5. 力扣(LeetCode)13. 罗马数字转整数

    罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II ,即为两个并 ...

  6. ArcFace2 #C 视频人脸比对教程

    请允许我大言不惭,叫做教程,特希望各位能指正.哦,我用的是vs2017.使用虹软技术 一.准备工作1.创建项目 2.添加EMGU.CV包 3.复制虹软的dll到项目 ,并设属性“复制到输出目录”为“如 ...

  7. mac软件

    1. http://www.ifunmac.com/ 2.Mac安装软件时提示已损坏的解决方法 http://www.jianshu.com/p/3d04a2292fcd 3.mac以后有时间在装的软 ...

  8. Asp.net core 学习笔记 ( User Secrets )

    参考 : http://cnblogs.com/nianming/p/7068253.html https://docs.microsoft.com/en-us/aspnet/core/securit ...

  9. 安卓自动化测试——rf

    ${a} Get Text //android.widget.TextView[contains(@text,"历史位置")]/../../../android.widget.Li ...

  10. Linux 各种软件的安装-Apache + php 篇

    mysql装好了,三剑客还差两个 apache就简单多了. yum -y install httpd # 删除默认欢迎页面 rm -f /etc/httpd/conf.d/welcome.conf s ...