java中线程池的使用方法
1 引入线程池的原因
由于线程的生命周期中包括创建、就绪、运行、阻塞、销毁阶段,当我们待处理的任务数目较小时,我们可以自己创建几个线程来处理相应的任务,但当有大量的任务时,由于创建、销毁线程需要很大的开销,运用线程池这些问题就大大的缓解了。
2 线程池的使用
我们只需要运用Executors类给我们提供的静态方法,就可以创建相应的线程池:
public static ExecutorSevice newSingleThreadExecutor()
public static ExecutorSevice newFixedThreadPool()
public static ExecutorSevice newCachedThreadPool()
newSingleThreadExecutor返回以个包含单线程的Executor,将多个任务交给此Exector时,这个线程处理完一个任务后接着处理下一个任务,若该线程出现异常,将会有一个新的线程来替代。
newFixedThreadPool返回一个包含指定数目线程的线程池,如果任务数量多于线程数目,那么没有没有执行的任务必须等待,直到有任务完成为止。
newCachedThreadPool根据用户的任务数创建相应的线程来处理,该线程池不会对线程数目加以限制,完全依赖于JVM能创建线程的数量,可能引起内存不足。
我们只需要将待执行的任务放入run方法中即可,将Runnable接口的实现类交给线程池的execute方法,作为它的一个参数,如下所示:
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(new Runnable(){
public void run(){
//执行的任务
}
}
如果需要给任务传递参数,可以通过创建一个Runnable接口的实现类来完成。
3 线程池使用的示例
下面我们通过一个实例来说明线程池的使用方法,该实例模仿子HADOOP中作业初始化过程,也即利用线程池从队列中取出作业并对作业进行初始化,其代码如下:
package com.yueliming.ThreadPool; import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class FixedThreadPool { public static List<Double> queue;
public ExecutorService threadPool; public FixedThreadPool() {
queue = new ArrayList<Double>();
//产生一个 ExecutorService 对象,这个对象带有一个大小为 poolSize 的线程池,若任务数量大于 poolSize ,任务会被放在一个 queue 里顺序执行。
threadPool = Executors.newFixedThreadPool(5);
} public static void main(String[] args) {
FixedThreadPool outer = new FixedThreadPool();
FixedThreadPool.Manager inner = outer.new Manager();
Thread consumer = new Thread(inner); Thread producer = new Thread() {//用于向queue中放入数据
public void run() {
while (true) {
synchronized (queue) {
double time = 1d;
long startTime = System.currentTimeMillis();
if (System.currentTimeMillis() - startTime >= time) {
startTime = System.currentTimeMillis();
for (int i = 0; i < 10; i++) {
queue.add((Math.random() * 10000));
}
queue.notify();
}
}
}
}
};
consumer.start();//启动守护线程,采用线程池来从queue中读取数据
producer.start();
} class Manager implements Runnable {
int num = 0;
public void run() {
while (true) {
try {
synchronized (queue) {
System.out.println("队列的长度为:" + queue.size());
while (queue.isEmpty()) {
queue.wait();
}
double result = queue.remove(0);
num++;
System.out.println("成功从队列中取到数据!" + num);
threadPool.execute(new ExecutorThread(result));
}
} catch (InterruptedException t) {
break;
}
}
threadPool.shutdown();
}
} class ExecutorThread implements Runnable { private double value; public ExecutorThread(double value) {
this.value = value;
} public void run() {
System.out.println("This is " + Thread.currentThread().getName() + " " + value);
}
}
}
其中内部类Manager为一个线程负责从队列中获取作业,并交给线程池去处理任务,有一个线程专门将数据放入到队列中,也即每隔1ms向队列中放入10个数据。
java中线程池的使用方法的更多相关文章
- Java中线程池,你真的会用吗?
在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及基本原理. 在文中有这样一段描述: 可以通过Executors静态工厂构建线程池,但一般不建 ...
- 沉淀再出发:java中线程池解析
沉淀再出发:java中线程池解析 一.前言 在多线程执行的环境之中,如果线程执行的时间短但是启动的线程又非常多,线程运转的时间基本上浪费在了创建和销毁上面,因此有没有一种方式能够让一个线程执行完自己的 ...
- Java中线程池,你真的会用吗?ExecutorService ThreadPoolExcutor
原文:https://www.hollischuang.com/archives/2888 在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及 ...
- Java中线程池的学习
线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理.当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程 ...
- Java中线程池的实现原理
知识点总结 ---------------------------------------------------------------------------------------------- ...
- Java中线程池的实现原理-求职必备
jdk1.5引入Executor线程池框架,通过它把任务的提交和执行进行解耦,只需要定义好任务,然后提交给线程池,而不用关心该任务是如何执行.被哪个线程执行,以及什么时候执行. 初始化线程池(4种) ...
- JAVA中线程池的简单使用
比如现在有10个线程,但每次只想运行3个线程,当这3个线程中的任何一个运行完后,第4个线程接着补上.这种情况可以使用线程池来解决,线程池用起来也相当的简单,不信,你看: package com.dem ...
- java中线程池的几种实现方式
1.线程池简介: 多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力. 假设一个服务器完成一项任务所需时间为:T1 创建 ...
- 第九章 Java中线程池
Java中的线程池是运用场景最多的并发框架,几乎所有需求异步或并发执行任务的程序都可以使用线程池.在开发过程中,合理地使用线程池能够带来3个好处. 降低资源消耗:通过重复利用已创建的线程降低线程创建和 ...
随机推荐
- TSQL基础(三)
字符处理函数 sql中常见的字符类型有: char(n) --长度固定 不可变 非Unicode 字符数据 n 必须是一个介于 1 和 8,000 之间的数值 nchar(n) --长度固定 不可变 ...
- cv::mat转换成QImage的问题
在进行cv::mat转换为QImage过程中,经常出现问题: cv::Mat image; ...QImage img=QImage((const unsigned char*)(image.data ...
- 第五篇、微信小程序-swiper组件
常用属性: 效果图: swiper.wxml添加代码: <swiper indicator-dots="{{indicatorDots}}" autoplay="{ ...
- 第六篇、AVplayer定制视频播放控件
1.引用头文件#import AVFoundation 2.自定义AVPlayer(播放的机器) 3.自定义AVPlayerItem(胶片) >> 视频的URL转成AVAsset 4.AV ...
- poj 3614 Sunscreen
...
- Linux C 程序 指针数组和二级指针(TEN)
指针数组和二级指针 #include<stdio.h> int main(){ ] = {,,,,}; ], i; int **pp = p; //使p指针数组指向每一个a ; i < ...
- jackson 解析结合类(需要传入Class, 和 Class.Class, 回调方法是List<Class>)
import java.util.HashMap; import java.util.List; import org.codehaus.jackson.map.ObjectMapper; impor ...
- CSS实现不固定宽度和高度的自动居中
有时候我们需要实现下面这种效果: 嘎嘎,撑大高度不让你剧中 嘎嘎,撑大高度不让你剧中 嘎嘎,撑大高度不让你剧中 嘎嘎,撑大高度不让你剧中 嘎嘎,撑大高度不让你剧中 嘎嘎,撑大高度不让你剧中 嘎嘎,撑大 ...
- angularJs--$on、$emit和$broadcast的使用
$emit只能向parent controller传递event与data $broadcast只能向child controller传递event与data $on用于接收event与data 例子 ...
- 部门招聘开发人员(python相关)
岗位职责: 1.参与需求分析,产品设计,功能开发: 2.负责系统平台的日常维护: 3.与团队技术交流,共同进步 任职要求: 1.精通Python:对Python有兴趣. 2.熟悉MVC架构,精通Dja ...