java核心知识点 --- 线程池ThreadPool
线程池是多线程学习中需要重点掌握的.
系统启动一个新线程的成本是比较高的,因为它涉及与操作系统交互.在这种情形下,使用线程池可以很好的提高性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考虑使用线程池.
一.如何创建线程池??
在Java5之前,线程池都是开发才手动实现的,从Java5开始,Java内建支持线程池.主要是新增了一个executors工厂类来生产线程池.
1.newCachedThreadPool():创建一个具有缓存功能的线程池,系统根据需要创建线程,这些线程将会被缓存到线程池中.
2.newFixedThreadPool(int nThreads):创建一个可重用的,具有固定线程数的线程池.
3.newSingleThreadExecutor():创建一个只有单线程的线程池,它相当于调用newFixedThreadPool()方法传入参数为1;
4.newScheduledThreadPool(int corePoolSize)指池中所保存的线程数,即使线程是空闲的也被保存在线程池内;
5.newSingleThreadScheduledExecutor():创建只有一个线程的线程池,它可以在指定延迟后执行线程任务;
上面5个方法中的前3个方法返回一个ExecutorService对象,该对象代表一个线程池,它可以执行Runnable对象或Callable对象所代表的线程;而后2个方法返回一个ScheduledExecutorService线程池,它是ExecutorService的子类.
二.如何使用线程池?
举例:

package com.amos.concurrent; import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; /**
* @ClassName: ThreadPoolTest
* @Description: java5中的线程池
* @author: amosli
* @email:hi_amos@outlook.com
* @date Apr 21, 2014 2:13:27 AM
*/
public class ThreadPoolTest { public static void main(String[] args) {
// ExecutorService executorService = Executors.newFixedThreadPool(3);//设置固定的线程数
// ExecutorService executorService = Executors.newCachedThreadPool();//创建带缓存的线程池,自动分配线程数
ExecutorService executorService = Executors.newSingleThreadExecutor();//创建单一线程池,如何实现线程死了,马上自动重新建一个
Executors.newScheduledThreadPool(3).schedule(new Runnable() {//创建一个有3个线程数的线程池,批定3秒后执行run方法里的内容
public void run() {
System.out.println("bomb.....");
}
}, 3, TimeUnit.SECONDS );//隔3秒 for (int i = 0; i < 10; i++) {//创建10个任务
final int task = i;
executorService.execute(new Runnable() {//执行任务的线程
public void run() {
for (int i = 0; i < 10; i++) {//循环执行10个次
System.out.println(Thread.currentThread().getName() + " loop" + i + " task is" + task);
}
}
});
}
System.out.println("all of 10 task has committed!!");
List<Runnable> shutdownNow = executorService.shutdownNow();//立即关闭线程,并返回未执行的线程
System.out.println("closed thread size:"+shutdownNow.size());
for(Runnable a:shutdownNow){
System.out.println(a);
}
}
}

运行效果:

创建一个单一的线程池,将任务加入了线程池,被关闭的线程有9个,在3秒后执行了输出'bomb....'
三.线程池使用注意事项
1.日常开发中Executors.newFixedThreadPool()是比较常用到的.
2.如何定时执行任务?
在执行指定时间执行任务时,比如要在中午12:00时运行一次,那么可以schedule(task, date.getTime() -
System.currentTimeMillis(), TimeUnit.MILLISECONDS).也即时采用倒计时的方式去执行定时操作,这个是Java官方文档建议使用的.
3.扩展---每隔2秒运行一次任务,持续一个小时

package com.amos.concurrent; import static java.util.concurrent.TimeUnit.SECONDS; import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture; class BeeperControl {
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); public void beepForAnHour() {
final Runnable beeper = new Runnable() {
public void run() {
System.out.println(new Date().getSeconds());//计时
System.out.println("beep");
}
};
final ScheduledFuture beeperHandle = scheduler.scheduleAtFixedRate(beeper, 10, 2, SECONDS);//任务,10s delay,2s/次,单位秒 scheduler.schedule(new Runnable() {
public void run() {
beeperHandle.cancel(true);//撤消任务
}
}, 60 * 60, SECONDS);//60*60s=60min=1h
}
}
public class test{
public static void main(String[] args) {
System.out.println(new Date().getSeconds());//计时
new BeeperControl().beepForAnHour();
}
}

这个例子,是java官方提供的,这里稍做了修改,运行效果如下:

注:第一次运行是在0秒,10秒后开始第一次beep,然后每隔2秒beep一次;
这里首先是创建一个任务线程池: Executors.newScheduledThreadPool(1),设置了线程数为1,然后实现了一个runnable接口,再然后就是调用了scheduleAtFixedRate方法,指定频率,指定延时,执行beep任务,最后又实现了一个runnable接口,延时1小时执行撤消线程的任务.
java核心知识点 --- 线程池ThreadPool的更多相关文章
- Java核心知识点 --- 线程中如何创建锁和使用锁 Lock , 设计一个缓存系统
理论知识很枯燥,但这些都是基本功,学完可能会忘,但等用的时候,会发觉之前的学习是非常有意义的,学习线程就是这样子的. 1.如何创建锁? Lock lock = new ReentrantLock(); ...
- Java核心复习——线程池ThreadPoolExecutor源码分析
一.线程池的介绍 线程池一种性能优化的重要手段.优化点在于创建线程和销毁线程会带来资源和时间上的消耗,而且线程池可以对线程进行管理,则可以减少这种损耗. 使用线程池的好处如下: 降低资源的消耗 提高响 ...
- Java核心知识点学习----使用Condition控制线程通信
一.需求 实现线程间的通信,主线程循环3次后,子线程2循环2次,子线程3循环3次,然后主线程接着循环3次,如此循环3次. 即:A->B->C---A->B->C---A-> ...
- Java核心知识点学习----线程中如何创建锁和使用锁 Lock,设计一个缓存系统
理论知识很枯燥,但这些都是基本功,学完可能会忘,但等用的时候,会发觉之前的学习是非常有意义的,学习线程就是这样子的. 1.如何创建锁? Lock lock = new ReentrantLock(); ...
- Java高并发 -- 线程池
Java高并发 -- 线程池 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 在使用线程池后,创建线程变成了从线程池里获得空闲线程,关闭线程变成了将线程归坏给线程池. ...
- java并发之线程池的使用
背景 当系统并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要消耗大量的系统资源. 所以需要一个办法使得线程可以 ...
- 完全解析线程池ThreadPool原理&使用
目录 1. 简介 2. 工作原理 2.1 核心参数 线程池中有6个核心参数,具体如下 上述6个参数的配置 决定了 线程池的功能,具体设置时机 = 创建 线程池类对象时 传入 ThreadPoolExe ...
- Android 多线程: 完全解析线程池ThreadPool原理&使用
目录 1. 简介 2. 工作原理 2.1 核心参数 线程池中有6个核心参数,具体如下 上述6个参数的配置 决定了 线程池的功能,具体设置时机 = 创建 线程池类对象时 传入 ThreadPoolExe ...
- JAVA多线程(三) 线程池和锁的深度化
github演示代码地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-servic ...
随机推荐
- linux vi详解
刚开始学着用linux,对vi命令不是很熟,在网上转接了一篇. vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指 ...
- CSU1612Destroy Tunnels(强连通)传递闭包
Destroy Tunnels 原来早忘记了离散里含有这么一个叫传递闭包的东西 矩阵A的闭包B = A U A^2 U A^3 U ... 所以这里直接如果A[i][j]!= 0,建边i->j跑 ...
- linux各个文件作用
linux下的文件结构,看看每个文件夹都是干吗用的/bin 二进制可执行命令 /dev 设备特殊文件 /etc 系统管理和配置文件 /etc/rc.d 启动的配置文件和脚本 /home 用户主目录的基 ...
- c/c++中system函数在Linux和windows下区别
windows 在windows下的system函数中命令可以不区别大小写! 功 能: 发出一个DOS命令 #include <stdlib.h> int system(char *com ...
- python 有关引用的一些问题
python 有关引用的一些问题 print id.__doc__ id(object) -> integer Return the identity of an object. This ...
- RK3288 OTG切换为Host模式
OTG = On The Go,是USB的一种工作模式 USB协议中规定了两类设备,一类是Host.一类是Device. Host为主控设备,如PC,Device为从设备,如鼠标.U盘等,Device ...
- 手动下载阿里云Nexus上的Jar包
手动下载阿里云Nexus上的Jar包 1.1 在任意目录下创建一个文件夹,创建一个pom.xml文件,一个bat批处理脚本,如图: 1.2 DownLoad.bat文件中的内容: call mvn - ...
- MQTT的知识点
问题一:单片机缓存有限,处理能力有限的情况下,消息不可能一次发出,这种情况下要怎样通过MQTT发布消息? 先组装publish协议的头,里面写好payload的长度,通过tcp发出去,然后一点一点发p ...
- web开发视频(一)之环境准备
硬件环境: Win7+64位操作系统 1.安装 jdk.tomcat.eclipse; 2.配置 jdk 环境变量.tomcat环境变量 (jdk配置成功的标示是在命令提示符中输入 javac 给出对 ...
- NoSQL v.s. RDB
RDB 相对于 NoSQL 的劣势: 1. 集中式单点架构 2. 固定的数据模型: 可扩展性差,缺乏处理半结构化和非结构化数据的能力. 3. 扩容成本高:处理海量数据时存在性能瓶颈,大数据时代的存储需 ...