1.使用线程池的好处

  

2.JUC中几种常用的线程池

  java.util.concurrent包下的Executors工厂类,提供了一系列的线程池的创建方法,其构造方法如下:

    public ThreadPoolExecutor(int corePoolSize,              //线程池线程核心数量,线程池维护线程的最少数量
int maximumPoolSize,     //线程池最大线程数量
long keepAliveTime,           //空闲线程存活时间
TimeUnit unit,              //存活时间的时间单位
BlockingQueue<Runnable> workQueue,  //存储任务的线程队列
ThreadFactory threadFactory,      //线程工厂
RejectedExecutionHandler handler) { //拒绝策略
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}

其中常用的线程池有四种,分别是fixedThreadPool、cachedThreadPool、ScheduledThreadPool和SingleThreadExecutor。他们分别适用在不同的场合。

2.1  newFixedThreadPool

特点:

    • 用于创建一个可重用、固定线程数量的线程池;
    • 当线程池中线程都处于运行中时,新来的线程会进入等待状态,直到线程池中出现一个空闲线程;
    • 当一个线程在任务中途退出、终止时,会有一个新的线程来替代它继续完成后面未完成的任务。
    • 除非采用显式关闭的方法去关闭某个线程,否则线程会一直存在,不会释放资源。
    • 任务存储在无界阻塞队列中
    • 适用场景:长期任务

构造方法:

    public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}

实例代码:  

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.Test; public class ExecutorsTest extends Thread{
private int index;
public ExecutorsTest(int i)
{
this.index = i;
} public void run()
{
try
{
System.out.println("[Thread"+this.index+"]" +"start..");
Thread.sleep((int)(Math.random()*10000));
System.out.println("[Thread"+this.index+"]" + "end");
}catch(Exception e)
{
e.printStackTrace();
}
} public static void main(String args[])
{
ExecutorService service = Executors.newFixedThreadPool(4); for(int i=0;i<10;i++)
{
service.execute(new ExecutorsTest(i));
}
service.shutdown(); }
}

因为线程池中线程数量一共有4个,所以当一次有大于4个的任务需要执行时,因为线程池中无空闲线程,后续任务进入等待状态,当其他任务执行完毕后,线程空闲,则马上开始执行正在等待的任务。

2.1  newCachedThreadPool

特点:

  • 线程池数量上限为:Integer.MaxValue(2147483647);
  • 线程池默认空闲60S,超过60S会从线程池中移除;
  • 新来任务时,先检查是否有空闲线程可使用,若无,则创建一个新线程执行任务;
  • 任务存储在同步队列中。
  • 适用场景:短时异步任务。

构造函数:

    public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}

示例代码:

 import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import org.junit.Test; public class ExecutorsTest extends Thread{
private int index;
public ExecutorsTest(int i)
{
this.index = i;
} public void run()
{
try
{
System.out.println("[Thread"+this.index+"]" +"start..");
Thread.sleep((int)(Math.random()*1000));
System.out.println("[Thread"+this.index+"]" + "end");
}catch(Exception e)
{
e.printStackTrace();
}
} public static void main(String args[])
{
ExecutorService service = Executors.newCachedThreadPool(); for(int i=0;i<10;i++)
{
service.execute(new ExecutorsTest(i));
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} for(int i=0;i<5;i++)
{
service.execute(new ExecutorsTest(i));
} service.shutdown(); }

创建10个工作线程用于处理任务,当线程执行完毕后,处于空闲状态,此时若出现新的任务,则会从线程池中用空闲的线程来处理新的任务。若没有空闲线程,则开启新线程处理。

2.3  newSingleThreadExecutor

特点:

  • 创建一个单个Worker的线程;
  • 线程会按照顺序依次执行;
  • 任务存储在无界阻塞队列中
  • 适用场景:需要按照顺序执行的任务。

构造方法:

    public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}

 实例代码:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import org.junit.Test; public class ExecutorsTest extends Thread{
private int index;
public ExecutorsTest(int i)
{
this.index = i;
} public void run()
{
try
{
System.out.println("[Thread"+this.index+"]" +"start..");
Thread.sleep((int)(Math.random()*1000));
System.out.println("[Thread"+this.index+"]" + "end");
}catch(Exception e)
{
e.printStackTrace();
}
} public static void main(String args[])
{
ExecutorService service = Executors.newSingleThreadExecutor(); for(int i=0;i<10;i++)
{
service.execute(new ExecutorsTest(i));
}
service.shutdown(); } }

出现多个任务时,SingleThreadExecutor会按照顺序依次执行各个任务。

2.4 newScheduledThreadPool

 特点:

  • 任务存储在无界延迟队列中
  • 适用场景:需要定期执行或延迟执行的任务

构造方法:

    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
} public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}

实例代码一(scheduleAtFixedRate的使用)

import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; public class ExecutorsTest2 extends Thread{
private int index;
public ExecutorsTest2()
{
} public void run()
{
try
{
System.out.println("[Current Time is "+new Date().toString()); }catch(Exception e)
{
e.printStackTrace();
}
} public static void main(String args[])
{
/*
* 执行定时任务newScheduledThreadPool
*/
ScheduledExecutorService service = Executors.newScheduledThreadPool(10); //5秒后开始执行,每隔一秒执行一次
service.scheduleAtFixedRate(new ExecutorsTest2(), 5, 1, TimeUnit.SECONDS);
}
}

scheduleAtFixedRate方法,一共四个参数,分别是:需要执行的任务task、延迟执行时间t1、每次执行任务的时间间隔t2、时间间隔单位。
含义是:在t1时间过后,以 1次/t2 的频率来不断执行 task。
上述代码中,在5秒延迟后,以 1次/1秒的频率执行 打印当前时间的任务。

实例代码二scheduleWithFixedDelay的使用):

 import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; public class ExecutorsTest3 extends Thread{
private int index;
public ExecutorsTest3()
{
} public void run()
{
try
{
//每次任务大约耗时1秒
Thread.sleep(1000);
System.out.println("[Current Time is "+new Date().toString()); }catch(Exception e)
{
e.printStackTrace();
}
} public static void main(String args[])
{
/*
* 执行定时任务newScheduledThreadPool
*/
ScheduledExecutorService service = Executors.newScheduledThreadPool(10); //5秒后开始执行,每次任务执行完后延迟3秒后,继续执行下一次
service.scheduleWithFixedDelay(new ExecutorsTest3(), 5, 3, TimeUnit.SECONDS);
}
}

scheduleWithFixedDelay也是四个参数,分别是:待执行的任务Task,延迟时间t1,每次任务执行完毕后延迟t2秒后执行下次任务,延迟时间单位。

浅析java中的四种线程池的更多相关文章

  1. Java 1.ExecutorService四种线程池的例子与说明

    1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() { @Override public void run() { ...

  2. JAVA中的4种线程池的使用

    Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程.newFixe ...

  3. Java 中的几种线程池,你之前用对了吗

    好久不发文章了,难道是因为忙,其实是因为懒.这是一篇关于线程池使用和基本原理的科普水文,如果你经常用到线程池,不知道你的用法标准不标准,是否有隐藏的 OOM 风险.不经常用线程池的同学,还有对几种线程 ...

  4. Java 中的几种线程池这么用才是对的

    为什么要使用线程池 虽然大家应该都已经很清楚了,但还是说一下.其实归根结底最主要的一个原因就是为了提高性能. 线程池和数据库连接池是同样的道理,数据库连接池是为了减少连接建立和释放带来的性能开销.而线 ...

  5. Java 四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor

    介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new T ...

  6. Java四种线程池

    Java四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor 时间:20 ...

  7. Java四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor

    1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? Java new Thread(new Runnable() { @Override public void ru ...

  8. JAVA四种线程池实例

    1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗?   Java   1 2 3 4 5 6 7 new Thread(new Runnable() {        ...

  9. Java 四种线程池的用法分析

    1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() { @Override public void run() { ...

随机推荐

  1. Python实现串口通信(pyserial)

    pyserial模块封装了对串口的访问,兼容各种平台. 安装 pip insatll pyserial 初始化 简单初始化示例 import serial ser = serial.Serial('c ...

  2. Delphi 画布对象

    樊伟胜

  3. 3、Rsync备份服务实战

    1.Rsync基本概述 rsync是一款开源的备份工具,可以在不同主机之间进行同步,可实现全量备份与增量备份,因此非常适合用于架构集中式备份或异地备份等应用. rsync官方地址:传送门http:// ...

  4. python文件操作:文件处理案例

    储存一个文件,文件上有多个用户名,密码,做一个认证的流程程序,首先创建一个文件,文件上输入多个用户名,及对应的密码,然后让客户输入用户名和密码,进行用户名和密码核对,如果输入正确,则的认证成功,bre ...

  5. 解决remix在线编译器连接本地私有链环境不成功的问题

    一.部署合约到私有链环境 选择"environment"里的"Web3 Provider" 弹出RPC连接地址输入框 输入我们Geth客户端安装服务器的IP:9 ...

  6. 【转载】MCMC和Gibbs Sampling算法

    转载随笔,原贴地址:MCMC和Gibbs Sampling算法 本文是整理网上的几篇博客和论文所得出来的,所有的原文连接都在文末. 在科学研究中,如何生成服从某个概率分布的样本是一个重要的问题.如果样 ...

  7. 最全的PHP正则表达式

    一.校验数字的表达式 1 数字:^[0-9]*$2 n位的数字:^\d{n}$3 至少n位的数字:^\d{n,}$4 m-n位的数字:^\d{m,n}$5 零和非零开头的数字:^(0|[1-9][0- ...

  8. python+request+HTMLTestRunner+unittest接口自动化测试框架

    转自https://my.oschina.net/u/3041656/blog/820023 正在调研使用python进行自动化测试,在网上发现一篇比较好的博文,作者使用的是python3,但目前自己 ...

  9. Eclipse快捷方式早知道!Productive Workflow不再是问题

    MyEclipse CI 2019.4.0安装包下载 本文将为大家介绍Eclipse快捷方式列表,希望可以帮助您提供工作效率.快捷方式主要分以下几个区域: 导航 通用编辑 Java编辑器 插件开发 工 ...

  10. python中的堆和栈

    内存中的堆栈和数据结构堆栈不是一个概念,可以说内存中的堆栈是真实存在的物理区,数据结构中的堆栈是抽象的数据存储结构.内存空间在逻辑上分为三部分:代码区.静态数据区和动态数据区,动态数据区又分为栈区和堆 ...