JAVA 线程池入门事例
线程池这个概念已经深入人心了,今天就是通过几个入门事例,学习一下线程池在JAVA中的应用。
一、大小固定的线程池——Executors.newFixedThreadPool()
下面咱们明确两个类:
1、ExecutorService:线程池的接口类
2、Executors:Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具
3、Executors.newFixedThreadPool():这是一个静态方法,也是这个事例的核心,目的是创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大值。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
package com.taobao.threadpool; import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService; /**
* 线程池的应用
* @author liqiu
*
*/
public class Test {
public static void main(String[] args) {
// 创建一个可重用固定线程数的线程池
ExecutorService pool = Executors.newFixedThreadPool(3);
// 将线程放入池中进行执行
for (int i=0; i<9; i++){
pool.execute(new MyThread(i));
}
// 关闭线程池
pool.shutdown();
}
} class MyThread extends Thread {
int num;
public MyThread(int i){
this.num = i;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "正在执行。。。" + this.num);
}
}
执行的结果:
pool-1-thread-1正在执行。。。0
pool-1-thread-1正在执行。。。3
pool-1-thread-1正在执行。。。4
pool-1-thread-3正在执行。。。2
pool-1-thread-3正在执行。。。6
pool-1-thread-3正在执行。。。7
pool-1-thread-3正在执行。。。8
pool-1-thread-2正在执行。。。1
pool-1-thread-1正在执行。。。5
二、其他的Executores方法
1、Executors.newSingleThreadExecutor():创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。这种用法我认为违背了线程池的概念,毕竟是一个池子,竟然只有一条鱼,很没劲。事例和上一个一样,有兴趣的话自己试一试。
2、Executors.newCachedThreadPool():创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。说白了就是默认有若干个线程,如果请求增多了,也会继续增加线程的个数,但是会自动自动回收超出的部分线程。
3、Executors.newScheduledThreadPool():创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。
4、Executors.newSingleThreadExecutor():创建一个单线程的线程池。此线程池支持定时以及周期性执行任务的需求。
三、自定义线程池
阅读了上面的内容,应该已经可以使用JAVA提供的线程池了,但是有一个特殊的情况还是需要咱们特制线程池。
package com.taobao.threadpool; import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; /**
* 线程池的应用
*
* @author liqiu
*
*/
public class Test {
public static void main(String[] args) {
// 创建等待队列
BlockingQueue bqueue = new ArrayBlockingQueue(20);
// 创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行。
ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 3, 2, TimeUnit.MILLISECONDS, bqueue);
// 创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口
for (int i = 0; i <= 9; i++) {
// 将线程放入池中进行执行
pool.execute(new MyThread(i));
}
// 关闭线程池
pool.shutdown();
}
} class MyThread extends Thread {
int num;
public MyThread(int i){
this.num = i;
}
@Override
public void run() {
System.out.println(this.num+" 正在被"+Thread.currentThread().getName() + "执行。。。");
try {
Thread.sleep(100L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
执行的结果:
0 正在被pool-1-thread-1执行。。。
1 正在被pool-1-thread-2执行。。。
2 正在被pool-1-thread-1执行。。。
3 正在被pool-1-thread-2执行。。。
4 正在被pool-1-thread-1执行。。。
5 正在被pool-1-thread-2执行。。。
6 正在被pool-1-thread-1执行。。。
7 正在被pool-1-thread-2执行。。。
8 正在被pool-1-thread-1执行。。。
9 正在被pool-1-thread-2执行。。。
下面解释一下程序:
ThreadPoolExecutor 类的方法:
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue)
参数说明名如下:
corePoolSize - 池中所保存的线程数,包括空闲线程。
maximumPoolSize - 池中允许的最大线程数。
keepAliveTime - 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
unit - keepAliveTime 参数的时间单位。
workQueue - 执行前用于保持任务的队列。此队列仅保持由 execute 方法提交的 Runnable 任务。本例实用的是BlockingQueue,有关它的内容可以参考:http://www.cnblogs.com/liqiu/p/3630281.html
小结:
可见用给定的初始参数和默认的线程工厂及处理程序创建新的 ThreadPoolExecutor。使用 Executors 工厂方法之一比使用此通用构造方法方便得多。
JAVA 线程池入门事例的更多相关文章
- Java线程池入门
序 为什么要用线程池?什么情况下才会用到线程池? 并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间. 因此 ...
- Java线程池入门必备
线程池 一. 线程池的简介 1.什么是线程池? 最早期的工作线程处理任务的模型.一个任务的到来,会伴随着线程的创建,当处理完任务后,线程会被销毁,资源回收.这种一个任务一个线程一系列创建销毁的模式 ...
- 深入浅出Java线程池:源码篇
前言 在上一篇文章深入浅出Java线程池:理论篇中,已经介绍了什么是线程池以及基本的使用.(本来写作的思路是使用篇,但经网友建议后,感觉改为理论篇会更加合适).本文则深入线程池的源码,主要是介绍Thr ...
- Java 线程池框架核心代码分析--转
原文地址:http://www.codeceo.com/article/java-thread-pool-kernal.html 前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和 ...
- Java线程池使用说明
Java线程池使用说明 转自:http://blog.csdn.net/sd0902/article/details/8395677 一简介 线程的使用在java中占有极其重要的地位,在jdk1.4极 ...
- (转载)JAVA线程池管理
平时的开发中线程是个少不了的东西,比如tomcat里的servlet就是线程,没有线程我们如何提供多用户访问呢?不过很多刚开始接触线程的开发攻城师却在这个上面吃了不少苦头.怎么做一套简便的线程开发模式 ...
- Java线程池的那些事
熟悉java多线程的朋友一定十分了解java的线程池,jdk中的核心实现类为java.util.concurrent.ThreadPoolExecutor.大家可能了解到它的原理,甚至看过它的源码:但 ...
- 四种Java线程池用法解析
本文为大家分析四种Java线程池用法,供大家参考,具体内容如下 http://www.jb51.net/article/81843.htm 1.new Thread的弊端 执行一个异步任务你还只是如下 ...
- Java线程池的几种实现 及 常见问题讲解
工作中,经常会涉及到线程.比如有些任务,经常会交与线程去异步执行.抑或服务端程序为每个请求单独建立一个线程处理任务.线程之外的,比如我们用的数据库连接.这些创建销毁或者打开关闭的操作,非常影响系统性能 ...
随机推荐
- python-opencv旋转图像,保持图像不被裁减
python-opencv旋转图像,保持图像不被裁减 import cv2 from math import * def remote(img,degree): #degree左转 img = c ...
- 【转】PHP笔试题2010年
From : http://www.51projob.com/a/PHP/20120905/602.html 下午,还有一场比较大的面试等着我[虽然接到pps的录用电话,可是心里还是想去verycd试 ...
- MSSQL2008 全文索引的创建
从MSSQL2008开始,全文索引推荐的创建方式已经与2005不同了.对于字符类型的数据库,可以直接创建. CREATE UNIQUE INDEX hr_job_idx ON hr_job_datab ...
- SpringBoot yml 配置 多配置文件,开发环境,生产环境配置文件分开
原文地址:https://www.cnblogs.com/baoyi/p/SpringBoot_YML.html 1. 在 spring boot 中,有两种配置文件,一种是application.p ...
- Oracle简单的备份和恢复-导出和导入(2)
ylbtech-Oracle:Oracle简单的备份和恢复-导出和导入(2) 简单的备份和恢复-导出和导入(2) 1. 用户导入导出文件中的一张表(emp)返回顶部 0.1, 我们在sql plus中 ...
- asp.net mvc源码分析-ModelValidatorProviders 客户端的验证
几年写过asp.net mvc源码分析-ModelValidatorProviders 当时主要是考虑mvc的流程对,客户端的验证也只是简单的提及了一下,现在我们来仔细看一下客户端的验证. 如图所示, ...
- VS2010整合NUnit进行单元测试
1.下载安装NUnit(最新win版本为NUnit-2.6.0.12051.msi) http://www.nunit.org/index.php?p=download 2.下载并安装VS的Visua ...
- oracle常用& to_date()怎么转换带am pm的时间格式
Oracle一.字符函数--大小写转换函数1.LOWER (strexp) 返回字符串,并将所有的字符小写. select lower('ABCDE') from dual --输出empbai ...
- Laravel 5 中使用 JWT(Json Web Token) 实现基于API的用户认证
在JavaScript前端技术大行其道的今天,我们通常只需在后台构建API提供给前端调用,并且后端仅仅设计为给前端移动App调用.用户认证是Web应用的重要组成部分,基于API的用户认证有两个最佳解决 ...
- Mahout 安装配置
http://log.medcl.net/item/2011/02/mahout_install/ Apache Mahout是一个机器学习的框架,构建在hadoop上支持大规模数据集的处理,目前最新 ...