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个好处. 降低资源消耗:通过重复利用已创建的线程降低线程创建和 ...
随机推荐
- fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
为完成老师的任务,用c++写个计算器,又去学点c++,结果就有各种问题,如题 http://www.cnblogs.com/newpanderking/articles/3372969.html 感谢 ...
- mysql绿色版在windows系统中的启动
mysql绿色版在windows系统中的启动 1.下载mysql免安装版 例如:mysql-5.7.11-winx64 2.修改配置文件,my-default.ini名称改为:my.ini,文件里面的 ...
- android 安装包签名问题探究
1.首先先科普一下,android为什么需要给安装包签名: 所有的Android应用程序在发布之前都要求开发人员用一个证书进行数字签名,anroid系统不会安装没有进行签名的由于程序. 平时我们 ...
- C++ 文件读写方案选型
严格来说, 有 3 种风格. UNIX 底层读写库 c 语言 stdio 标准库 iostream 流 一般的工程中, 底层读写库封装程度太低, 需要自己处理缓存和很多通用的异常场景. 不适合. 网络 ...
- JAVA_SE复习(OOP1)
面向对象编程(一) 一.继承 1. 在类图表示中,使用一个分为三块的矩形表示一个类.矩形的第一块表示类名,第二块描述这个类的属性及属性的数据类型,第三块描述这个类的操作,也就是方法以及返回类型. ...
- ubuntu后台配置无线网络
一.静态配置: 1.编辑 /etc/network/interfaces: auto loiface lo inet loopback auto wlan0iface wlan0 inet stati ...
- thinkphp3.2引入php 实例化类
如果你的类库没有采用命名空间的话,需要使用import方法先加载类库文件,然后再进行实例化,例如:我们定义了一个Counter类(位于Com/Sina/Util/Counter.class.php): ...
- java 枚举 类 enum
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializab ...
- Git 安装与使用(二)
一.分支管理 在Git里,master是主分支,同时可以创建其他分支,支持各分支合并到主分支上,基本命令如下 1.创建分支 git checkout -b dev 创建dev分支,并切换到 ...
- c#中的枚举
1.枚举概念:枚举是用户定义的整型类型,在声明一个枚举时,要指定该枚举的实例可以包含的一组可接受的值,还可以给值指定易于记忆的名称.如果在代码的某个地方,要试图把一个不可接受范围内的值赋予枚举的一个实 ...