JAVA4大线程池
不知不觉中我们电脑的硬件设施越来越好,从双核四线程普及到如今四核八线比比皆是。互联网发展至今,讲究的就是快,less is more,而且大数据的诞生和各种种类繁多的需求处理,单线程的程序逐渐不能满足一些业务需求。于是多线程就如此登上我们的舞台。
Java是如何实现和管理线程池的?
从JDK 5开始,把工作单元与执行机制分离开来,工作单元包括Runnable和Callable,而执行机制有Executor框架提供。在HotSpot VM的线程模型中,Java线程被一对一映射为本地操作系统线程。Java线程启动时会创建一个本地操作系统线程;当Java线程终止时,这个操作系统线程也会被回收。操作系统会调用所有线程并将他们分配给可用的CPU。
可以将此种模式分为两层,在上层,Java多线程程序通常把应用程序分解为若干任务,然后使用用户级的调度器(Executor框架)讲这些任务映射为固定数量的线程;在底层,操作系统内核将这些线程映射到硬件处理器上。
使用线程池的好处有很多:
1、降低资源消耗(线程无限制地创建,然后使用完毕后销毁,线程与线程之前切换占用的cpu资源也会大大减小,因为他们本身就是出自同一个容器资源中)
2、提高响应速度(无须再次创建线程)
3、提高线程的可管理性(我们可以自己在线程池中设置允许的最大线程数,线程空闲时的存活时间等等)
这里先简单介绍一下我们常用的已经在JDK中封装好的线程池:Executors,这里我们简单介绍常用的三个:
先上我的测试线程实现类:
package cn.com.sh.gx.crawler.extactor;
public class TestThreads implements Runnable {
private int index;
public TestThreads(int index) {
this.index=index;
}
@Override
public void run() {
while (true){
System.out.println("=======2222=====");
System.out.println(index);
try{
Thread.sleep(2000);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
以下的的方法调用的线程实现方法都是来自TestThreads。
一:newCachedThreadPool,
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程
public static void callBackThread(){
ExecutorService cachedThreadPool=Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int index = i;
cachedThreadPool.execute(new TestThreads(index));
}
}
我自己在这里在里面开了10个线程,但其实线程池可以为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。
二、newFixedThreadPool,
创建一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中
public static void getTaskThread(){
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
final int index = i;
fixedThreadPool.execute(new TestThreads(index));
}
}
我们可以看到,里面只有指定的5个线程在跑,虽然给开了10个,但是由于这run着的5个线程一直死循环(因为我实现方法是个死循环的实现),资源一直没有放,另外5个线程拿不到资源,当然,你可以在自己的实现方法里面不写死循环,这样其他的index也可以拿到数据去run了
三、getSingleThread
创建一个单线程化的Executor,即只创建唯一的工作者线程来执行任务,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。如果这个线程异常结束,会有另一个取代它,保证顺序执行。单工作线程最大的特点是可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的
public static void getSingleThread(){
ExecutorService singleThread=Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
singleThread.execute(new TestThreads(index));
}
}
我们可以看到这里的输入结果是依次输出,相当于顺序执行各个任务。这样的方法可以很好的保证线程安全性,但是性能得不到最大的提升。
四、newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。延迟执行示例代码如下:
public static void getScheduleThread(){
ScheduledExecutorService scheduleThread=Executors.newScheduledThreadPool(5);
for (int i = 0; i < 10; i++) {
final int index = i;
scheduleThread.schedule(new TestThreads(index),3, TimeUnit.SECONDS);
}
}
在这里我们为了可以看到效果,把实现方法死循环去掉。
变成这个样子:
@Override
public void run() {
// while (true){
System.out.println("=======2222=====");
System.out.println(index);
try{
Thread.sleep(2000);
}catch (Exception e){
e.printStackTrace();
}
// }
}
然后我们可以看到,我们运行的这个线程,延迟3S再执行的。interesting!
JAVA4大线程池的更多相关文章
- JAVA4种线程池的使用
Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.newFixe ...
- C#多线程和线程池 【转】
1.概念 1.0 线程的和进程的关系以及优缺点 windows系统是一个多线程的操作系统.一个程序至少有一个进程,一个进程至少有一个线程.进程是线程的容器,一个C#客户端程序开始于一个单独的线程,C ...
- C#多线程和线程池
1.概念 1.0 线程的和进程的关系以及优缺点 windows系统是一个多线程的操作系统.一个程序至少有一个进程,一个进程至少有一个线程.进程是线程的容器,一个C#客户端程序开始于一个单独的线程,C ...
- (转)websphere线程池 连接池设置
原文:http://www.talkwithtrend.com/Article/207511 池(Pool)是WebSphere中最常涉及的概念之一.从网络.Web 服务器.Web 容器.EJB 容器 ...
- C#多线程和线程池[转]
1.概念 1.0 线程的和进程的关系以及优缺点 windows系统是一个多线程的操作系统.一个程序至少有一个进程,一个进程至少有一个线程.进程是线程的容器,一个C#客户端程序开始于一个单独的线程,C ...
- [转]C#多线程和线程池
鸣谢原文:http://www.cnblogs.com/wwj1992/p/5976096.html 1.概念 1.0 线程的和进程的关系以及优缺点 windows系统是一个多线程的操作系统.一个程 ...
- Android进阶——多线程系列之四大线程池的使用介绍
线程池一直是初学者最抵触的东西,由于刚开始学习做项目并不会涉及到线程池的使用,但是不去学习它,心里又好像有个石头一直沉着,一直放心不下,其实是很简单的东西,早晚都要学,不如趁现在吧.由于文章从初学者的 ...
- Java线程池队列吃的太饱,撑着了咋整?java 队列过大导致内存溢出
Java的Executors框架提供的定长线程池内部默认使用LinkedBlockingQueue作为任务的容器,这个队列是没有限定大小的,可以无限向里面submit任务. 当线程池处理的太慢的时候, ...
- Java并发线程池到底设置多大?
前言 在我们日常业务开发过程中,或多或少都会用到并发的功能.那么在用到并发功能的过程中,就肯定会碰到下面这个问题 并发线程池到底设置多大呢? 通常有点年纪的程序员或许都听说这样一个说法 (其中 N 代 ...
随机推荐
- Math(2)
Math(2) public static void main(String[] args) { System.out.println(Math.floor(-32.8)); //常数 System. ...
- 详解MYSQL各种优化原理
说起MySQL的查询优化,相信大家收藏了一堆奇技淫巧:不能使用SELECT *.不使用NULL字段.合理创建索引.为字段选择合适的数据类型..... 你是否真的理解这些优化技巧?是否理解其背后的工作原 ...
- npm设置代理提高下载速度
*nix上给网络类程序设置代理的通用办法,即导出http_proxy/https_proxy环境变量对npm不起作用 需要用npm自己的配置命令来解决: npm set proxy $PROXY np ...
- 【jeasyui5】样式:调整页面显示的顶部菜单和左侧菜单
1.顶部菜单修改:修改index2.js里面的InitTopMenu方法,将icon +2 2.左侧菜单宽度调整: 修改index.html,加上width:170的定长 <!-- 左侧菜单 - ...
- java8 创建树结构的数据
private List<TreeNode> createTree(Integer pid, Map<Integer, List<SysPermission>> m ...
- 项目接入apm后错误报警总结
此文已由作者张磊授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 前言: 后端服务一般都有监控措施,一般可以及时发现线上错误,但是很多项目的前端却没有线上报警服务,即使有错误, ...
- JSONCPP介绍
描述JSON串 如何使用jsoncpp提供的数据结构来存储如下JSON串? // Configuration options { // Default encoding for text " ...
- Glusterfs冗余镜像(AFR)修复原理以及脑裂分析
研究Glusterfs半年多了,通过实际操作以及源代码分析,对它有了越来越深的了解,由衷的赞叹Gluster的整体架构.今天时间不早了,想写点关于Glusterfs的冗余镜像产生脑裂的原因. 首先,简 ...
- 洛谷P3102 [USACO14FEB]秘密代码Secret Code
P3102 [USACO14FEB]秘密代码Secret Code 题目描述 Farmer John has secret message that he wants to hide from his ...
- django进阶之缓存
Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层执行 ...