Java线程池快速学习教程
1. Java线程池
线程池:顾名思义,用一个池子装载多个线程,使用池子去管理多个线程。
问题来源:应用大量通过new Thread()方法创建执行时间短的线程,较大的消耗系统资源并且系统的响应速度变慢。【在一个什么程度上能够判断启用线程池对系统的资源消耗比启动定量的new Thread()资源消耗低?这个怎么测试?】【用户体验卡顿?慢?观察CPU百分比?】
解决办法:使用线程池管理短时间执行完毕的大量线程,通过重用已存在的线程,降低线程创建和销毁造成的消耗,提高系统响应速度。
2. Java线程池快速学习教程
2.1 创建线程池

图1 Executors静态方法图
2.2 线程池使用方法

图2 ExecutorService方法图
2.3 线程池快速使用举例
问题:线程池同时接受两个线程,两个线程分别执行打印0~100;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test {
public static #0000ff;">void main(String[] args) {
ExecutorService pool = Executors.newCachedThreadPool();
pool.submit(new TestThread());
pool.submit(new TestThread());
pool.shutdown();
}
}
class TestThread implements Runnable{
@Override
public void run(){
for(int i = 0; i <= 100; ++i){
System.out.println(Thread.currentThread().getName() + ": " + i);
try {
Thread.sleep( (long) (1000L * Math.random()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Test.java
3. 线程池原理:
3.1 线程池ThreadPoolExecutor
Executors类提供静态工厂方法,如图1所示,这些方法最终都是通过ThreadPoolExecutor类来实现。
构造函数如下所示:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
ThreadPoolExecutor.java
备注:
1、corePoolSize(线程池基本大小) >= 0;【当前最大并行运行线程数】
2、maximumPoolSize(线程池最大大小) >= 1;【当前最大创建线程数】
3、keepAliveTime(线程存活保持时间) >= 0;【线程在线程池空闲时间超过这个时间,会被终止掉】
4、workQueue(任务队列)不能为空;【用于传输和保存等待执行任务的阻塞队列】
5、handler(线程饱和策略)不能为空。【当线程池和队列已满的处理策略】
3.2 Executors类提供静态工厂方法默认参数
|
工厂方法 |
corePoolSize |
maximumPoolSize |
KeepAliveTime |
workQueue |
|
nreCachedThreadPool() |
0 |
Integer.MAX_VALUE |
60L |
SyschronousQueue |
|
newFixedThreadPool(int nThreads) |
nThreads |
nThreads |
0 |
LindedBlockingQueue |
|
newSingleThreadExecutor() |
1 |
1 |
0 |
LindedBlockingQueue |
|
newScheduledThreadPool(int corePoolSize) |
corePoolSize |
Integer.MAX_VALUE |
0 |
DelayedWorkQueue |
|
newSingleThreadScheduledExecutor() |
1 |
Integer.MAX_VALUE |
0 |
DelayedWorkQueue |
3.3 线程池添加任务过程
添加线程即提交任务,线程添加到线程池的过程:

图3 线程添加到线程池过程图
4. 总结:
1、根据需要生成线程池;
2、类实现Runnable中的run方法;
3、使用execute或submit方法提交任务;
4、线程池全部线程执行完毕并且不再需要线程池时,应用shutdown()关闭资源。
2016.09.17
5. 正式工作三个月后感想:
1、假设你只是想要一个线程执行完一些操作并且没有任何与其他线程进行通信与阻塞问题,你大概可以用匿名生成new Thread().start()方法来执行。
2、corePoolSize这个参数很重要,当前最大并行运行线程数,就是可以使用newSingleThreadExecutor创建单线程的线程池,将execute执行的任务,一个一个线程顺序执行摆脱锁的问题。
3、shutdown关闭线程池,但是会执行完已提交的任务,shutdownNow关闭线程池并关闭所有任务,切记。
2017.08.06
Java线程池快速学习教程的更多相关文章
- 【Java线程池快速学习教程】
1. Java线程池 线程池:顾名思义,用一个池子装载多个线程,使用池子去管理多个线程. 问题来源:应用大量通过new Thread()方法创建执行时间短的线程,较大的消耗系统资源并且系统的响应速度变 ...
- 【Java的JNI快速学习教程】
1. JNI简介 JNI是Java Native Interface的英文缩写,意为Java本地接口. 问题来源:由于Java编写底层的应用较难实现,在一些实时性要求非常高的部分Java较难胜任(实时 ...
- Java线程池详解(二)
一.前言 在总结了线程池的一些原理及实现细节之后,产出了一篇文章:Java线程池详解(一),后面的(一)是在本文出现之后加上的,而本文就成了(二).因为在写完第一篇关于java线程池的文章之后,越发觉 ...
- Java线程池学习
Java线程池学习 Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java ...
- Java四种线程池的学习与总结
在Java开发中,有时遇到多线程的开发时,直接使用Thread操作,对程序的性能和维护上都是一个问题,使用Java提供的线程池来操作可以很好的解决问题. 一.new Thread的弊端 执行一个异步任 ...
- Java线程池学习心得
一.普通线程和线程池的对比 new Thread的弊端如下: a. 每次new Thread新建对象性能差.b. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或o ...
- (转载)JAVA线程池管理
平时的开发中线程是个少不了的东西,比如tomcat里的servlet就是线程,没有线程我们如何提供多用户访问呢?不过很多刚开始接触线程的开发攻城师却在这个上面吃了不少苦头.怎么做一套简便的线程开发模式 ...
- Java 线程池(二)
简介 在上篇 Java 线程池(一) 我们介绍了线程池中一些的重要参数和具体含义,这篇我们看一看在 Java 中是如何去实现线程池的,要想用好线程池,只知其然是远远不够的,我们需要深入实现源码去了解线 ...
- 四种Java线程池用法解析
本文为大家分析四种Java线程池用法,供大家参考,具体内容如下 http://www.jb51.net/article/81843.htm 1.new Thread的弊端 执行一个异步任务你还只是如下 ...
随机推荐
- COGS 36. 求和问题
时间限制:1.2 s 内存限制:128 MB [问题描述] 在一个长度为n的整数数列中取出连续的若干个数,并求它们的和. [输入格式] 输入由若干行组成,第一行有一个整数n ...
- 关于 java swing 使用按钮关闭窗口
目的是给JButton添加点击操作,使指定JFrame窗口关闭. 网上不少说法是采用frame.dispose();的方法 但是采用frame.dispose();并没有使添加在frame上的wind ...
- Cannot fetch index base URL https://pypi.python.org/pypi/ 解决方法
vi /etc/resolv.conf # Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8) # ...
- [BZOJ3631]:[JLOI2014]松鼠的新家(LCA+树上差分)
题目传送门 题目描述: 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀 ...
- Kernel Stack Overflow(转)
0x00 漏洞代码 stack_smashing.c #include <linux/init.h> #include <linux/module.h> #include &l ...
- 歌乐第二弹:C++九九八十一
第一弹传送门:极乐净土 二话不说,上代码(注意事项在第一弹里): #include <windows.h> //q前缀为低音,g为高音,s前缀为半音阶 const int q1 = 131 ...
- 洛谷 P1126 机器人搬重物 (BFS)
题目链接:https://www.luogu.org/problemnew/show/P1126 吐槽:这题很阴险 一开始没把格子图转化成点图:30分 转化成点图,发现样例过不去,原来每步要判断vis ...
- bootstrap历练实例:复选框或单选按钮作为输入框组的前缀或后缀
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- graphviz layer 教程(非布局)
官方 pdf 上讲解的很少,没有图片. http://www.graphviz.org/wiki/how-use-drawing-layers-overlays 这里有图片,但是又没有说如何生成. 直 ...
- shell脚本,tee小工具的用法。
解释: tee是个工具 , 它的作用就是把标准输出,复制一份,扔文件里 ,原标准输出还输出,-a就相当于 >> 追加到文件里的意思. 不加就是 > 重定向到文件里去.