如同数据库连接一样,线程的创建、切换和销毁同样会耗费大量的系统资源。为了复用创建好的线程,减少频繁创建线程的次数,提高线程利用率可以引用线程池技术。使用线程池的优势有如下几点:
        1、保持一定数量的线程,减少了线程频繁创建和销毁资源消耗。
        2、使用线程的时候直接由线程池中取出线程,省去了创建线程的时间,侧面提高了系统的响应时间。
        3、需要使用线程的时候直接从线程池中取出,避免了人为的不合理创建线程,减少了潜在的风险。
Doug Lea在实现JUC中提供了原生的线程池,并提供了各种线程管理策略来适应于不同的使用场景。使用的时候可通过Executors获取各种线程池实例。

这里提供了六对12个方法来创建ExecutorService,其中每种类型的ExecutorService可以适用于不同的应用场景,对线程的管理策略也各不相同。下面就看一下各个方法的注释:

/**
* Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available.
* 创建一个线程池,需要的时候会创建新的线程,如果有可用的线程则会复用以前已经创建好的线程。
* These pools will typically improve the performance of programs that execute many short-lived asynchronous tasks.
* 这些线程池通常情况下可以提升哪些短期异步任务的性能
* Calls to {@code execute} will reuse previously constructed threads if available.
* 如果以创建的线程状态可用的话,调用execute可以复用他们
* If no existing thread is available, a new thread will be created and added to the pool.
* 如果不存在可用状态的线程,那么将会创建一个新线程同时会把该线程添加到线程池中
* Threads that have not been used for sixty seconds are terminated and removed from the cache.
*那些超过60s没用的线程将会被销毁同时从缓存中移除
* Thus, a pool that remains idle for long enough will not consume any resources.
*因此长时间空闲的线程池不会消耗任何资源
* Note that pools with similar properties but different details (for example, timeout parameters) may be created using {@link ThreadPoolExecutor} constructors.
*可以使用ThreadPoolExecutor创建性质相似但实现细节不同的线程池
* @return the newly created thread pool
*/ public static ExecutorService newCachedThreadPool(); //可以使用自定义的ThreadFactory 类创建线程,其它和无参方法一致
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory);
/**
* Creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue.
*创建一个可重用、固定数量线程的线程池
* At any point, at most {@code nThreads} threads will be active processing tasks.
*任何时间最多只有 nThreads 个线程被激活来执行任务
* If additional tasks are submitted when all threads are active, they will wait in the queue until a thread is available.
* 当无可用空闲线程的时候,如果有新任务被提交,这些新任务将会一直等待直至有可用线程来执行。
* If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.
*如果任何线程正常关闭之前在执行过程中因失败而提前终止,那么如果有未被执行的后续任务,则会创建新的线程来继续执行。
* The threads in the pool will exist until it is explicitly {@link ExecutorService#shutdown shutdown}.
* 线程池中的所有线程在明确掉用shutdown之后将会退出
*
* @param nThreads the number of threads in the pool
* @return the newly created thread pool
* @throws IllegalArgumentException if {@code nThreads <= 0}
*/
public static ExecutorService newFixedThreadPool(int nThreads);
//可自定义ThreadFactory
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory);
/**
* Creates a thread pool that can schedule commands to run after a given delay, or to execute periodically.
* 创建一个线程池,该线程在延迟指定时间之后可以周期性的执行线程体
* @param corePoolSize the number of threads to keep in the pool,
* even if they are idle
* @return a newly created scheduled thread pool 注意返回值类型是ScheduledExecutorService,不要使用ExecutorService来接收,否则找不到schedule执行方法
* @throws IllegalArgumentException if {@code corePoolSize < 0}
*/ public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize);
//可自定义ThreadFactory
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory);
/**
* Creates an Executor that uses a single worker thread operating off an unbounded queue.
*创建一个Executor,使用一个线程来工作,该线程存储在LinkedBlockingQueue中
* (Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.)
*注,如果任何线程正常关闭之前在执行过程中因失败而提前终止,那么如果有未被执行的后续任务,则会创建新的线程来继续执行。
* Tasks are guaranteed to execute sequentially, and no more than one task will be active at any given time.
* 任务是按顺序执行的,任何时间都只有一个线程来执行任务
* Unlike the otherwise equivalent {@code newFixedThreadPool(1)} the returned executor is guaranteed not to be reconfigurable to use additional threads.
*
* @return the newly created single-threaded Executor
*/ public static ExecutorService newSingleThreadExecutor();
//可自定义ThreadFactory
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory);
/**
* Creates a single-threaded executor that can schedule commands
* to run after a given delay, or to execute periodically.
* (Note however that if this single
* thread terminates due to a failure during execution prior to
* shutdown, a new one will take its place if needed to execute
* subsequent tasks.) Tasks are guaranteed to execute
* sequentially, and no more than one task will be active at any
* given time. Unlike the otherwise equivalent
* {@code newScheduledThreadPool(1)} the returned executor is
* guaranteed not to be reconfigurable to use additional threads.
* @return the newly created scheduled executor
*/ public static ScheduledExecutorService newSingleThreadScheduledExecutor(); public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory)

使用示例:

package thread.blogs.threadpool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; /**
* Created by PerkinsZhu on 2017/8/31 13:59.
*/
public class PoolTest { public static void main(String[] args) {
// testCachedThreadPool();
// testSingleThreadExecutor();
// testFixedThreadPool();
testScheduledThreadPool();
}
private static ThreadFactory myFactory = new MyThreadFactory(); private static void testSingleThreadExecutor() {
//一个一个的依次执行
doHandle(Executors.newSingleThreadExecutor(myFactory));
} private static void testFixedThreadPool() {
//两个两个的一起执行
doHandle(Executors.newFixedThreadPool(2,myFactory));
} private static void testCachedThreadPool() {
//10个一起一次性执行完
doHandle(Executors.newCachedThreadPool(myFactory));
} private static void testScheduledThreadPool() {
//定时周期执行
Executors.newScheduledThreadPool(1,myFactory).scheduleAtFixedRate(runnable, 500, 2000, TimeUnit.MILLISECONDS);
} private static Runnable runnable = () -> {
sleep(1000);
System.out.println(Thread.currentThread().getName() + " work!!!");
}; private static void doHandle(ExecutorService executorService) {
for (int i = 0; i < 10; i++) {
executorService.execute(runnable);
}
executorService.shutdown();
} private static void sleep(int time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} class MyThreadFactory implements ThreadFactory {//自定义ThreadFactory
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix; MyThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
namePrefix = "☆☆☆--" + poolNumber.getAndIncrement() + "-****-";
} public Thread newThread(Runnable r) {
Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
if (t.isDaemon()) {
t.setDaemon(false);
}
if (t.getPriority() != Thread.NORM_PRIORITY) {
t.setPriority(Thread.NORM_PRIORITY);
}
return t;
} }

在使用的时候必须明白各种线程池是否适用于自己的情景,选取合适的线程池进行使用。

=========================================

原文链接:多线程(七)JDK原生线程池转载请注明出处!

=========================================

---end

多线程(七)JDK原生线程池的更多相关文章

  1. 原生线程池这么强大,Tomcat 为何还需扩展线程池?

    前言 Tomcat/Jetty 是目前比较流行的 Web 容器,两者接受请求之后都会转交给线程池处理,这样可以有效提高处理的能力与并发度.JDK 提高完整线程池实现,但是 Tomcat/Jetty 都 ...

  2. java多线程系列六、线程池

    一. 线程池简介 1. 线程池的概念: 线程池就是首先创建一些线程,它们的集合称为线程池. 2. 使用线程池的好处 a) 降低资源的消耗.使用线程池不用频繁的创建线程和销毁线程 b) 提高响应速度,任 ...

  3. java核心-多线程(6)-线程池-ThreadPoolExecutor

    1.java多线程编程少不了使用线程池,线程池相关的工具类所在jdk包,java.util.concurrent 2.使用示例 demo1 public class ThreadPoolDemo { ...

  4. C#多线程之旅(3)——线程池

    v博客前言 先交代下背景,写<C#多线程之旅>这个系列文章主要是因为以下几个原因:1.多线程在C/S和B/S架构中用得是非常多的;2.而且多线程的使用是非常复杂的,如果没有用好,容易造成很 ...

  5. C# 多线程的自动管理(线程池) 基于Task的方式

    C# 多线程的自动管理(线程池) 在多线程的程序中,经常会出现两种情况:    1. 应用程序中线程把大部分的时间花费在等待状态,等待某个事件发生,然后给予响应.这一般使用 ThreadPool(线程 ...

  6. 第十章:Python高级编程-多线程、多进程和线程池编程

    第十章:Python高级编程-多线程.多进程和线程池编程 Python3高级核心技术97讲 笔记 目录 第十章:Python高级编程-多线程.多进程和线程池编程 10.1 Python中的GIL 10 ...

  7. java多线程总结五:线程池的原理及实现

    1.线程池简介:     多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.        假设一个服务器完成一项任务所需时间为:T1 创 ...

  8. Java多线程并发04——合理使用线程池

    在此之前,我们已经了解了关于线程的基本知识,今天将为各位带来,线程池这一技术.关注我的公众号「Java面典」了解更多 Java 相关知识点. 为什么使用线程池?线程池做的工作主要是控制运行的线程的数量 ...

  9. java多线程详解(7)-线程池的使用

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

随机推荐

  1. ARM开发(3)基于STM32的矩阵键盘控制蜂鸣器

    一 矩阵键盘控制蜂鸣器原理:  1.1 本实验实现8*7矩阵键盘上按键控制蜂鸣器响.  1.2 实验思路:根据电路图原理,找出矩阵键盘行列所对应的引脚,赋予对应的按键值,然后控制蜂鸣器响.  1.3 ...

  2. (转)上传jar包到nexus私服

    场景:在使用私服Nexus时候经常需要上传jar包,但是对上传jar包的方式不是很熟悉,所以很有必要学习下. 1 通过网页上传 GAV Definition:选择GAV Parameters 输入JA ...

  3. (转载) java:IO流学习小结

    今天刚刚看完Java的io流操作,把主要的脉络看了一遍,不能保证以后使用时都能得心应手,但是最起码用到时知道有这么一个功能可以实现,下面对学习进行一下简单的总结: IO流主要用于硬板.内存.键盘等处理 ...

  4. 【nodejs之我的开源module】 使用express搭建web服务器,代码即文档的实现。

    前言 都说nodejs适合制作restful_API,因为它有异步处理能力,能吞吐更多的请求,这一点是大家都认可的.前不久我使用nodejs+express+postgresql搭建了一个restfu ...

  5. [js高手之路] es6系列教程 - 函数的默认参数详解

    在ES6之前,我们一般用短路表达式处理默认参数 function show( a, b ){ var a = a || 10; var b = b || 20; console.log( a, b ) ...

  6. 微信小程序movable-view移动图片和双指缩放

    先从movable-view开始说起吧. movable-view是小程序自定义的组件.其描述为:"可移动的视图容器,在页面中可以拖拽滑动". 官方文档地址:https://mp. ...

  7. 解决js中post提交数据并且跳转到指定页面的问题总结

    今天在开发中过程中遇到了这个问题,js中利用JQuery中的 $.post("url", id, function(){}); 这个方法是数据提交正常,但是后台处理完成之后跳转无法 ...

  8. 从用eclipse还是idea所想到的

    最近一直在用idea做开发,刚开始用起来还是不熟,毕竟上次用idea还是研三在某知名互联网实习的时候,在学校和上家公司都用的是eclipse,然后就想,为什么有的公司用eclipse,有的公司用ide ...

  9. hdu 6121---Build a tree(深搜+思维)

    题目链接 Problem Description HazelFan wants to build a rooted tree. The tree has n nodes labeled 0 to n− ...

  10. php中自动加载类_autoload()和spl_autoload_register()实例详解

    一._autoload 自动加载类:当我们实例化一个未定义的类时,就会触此函数.到了php7.1以后版本不支持此函数好像抛弃了 新建一个类文件名字自己随便去:news类在auto.php文件里面去实例 ...