JDK并发包二

线程复用——线程池

在线程池中,总有那么几个活跃的线程,当程序需要线程时可以从池子中随便拿一个控线程,当程序执行完毕,线程不关闭,而是将这个线程退会到池子,等待使用。

JDK提供了一套Executor框架,可以有效进行线程控制。ThreadPoolExecutor表示一个线程池,Executors类相当与线程池工厂,通过Executors可以获得一个拥有特定功能的线程池。

Executors框架提供了各类线程池,主要有下面工厂方法

public static ExecutorService newFixedThreadPool(int nThreads);

public static ExecutorService newSingleThreadExecutor() ;

public static ExecutorService newCachedThreadPool();

public static ScheduledExecutorService newSingleThreadScheduledExecutor();

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize);

  • newFixedThreadPool()此方法返回一个有固定线程数量的线程池。当一个新的任务提交时,线程中若有空闲线程则立即执行,若无则会暂存在一个任务队列中,待有线程空闲时,再进行处理。
  • newSingleThreadExecutor()此方法返回一个只有一个线程的线程池,有新任务提交到线程池中会被安排到任务队列中,等待执行。
  • newCachedThreadPool()此方法返回一个根据实际情况调整线程数量的线程池,线程池中线程的数量不确定,若有新任务,线程池中有空闲线程,就复用空闲线程,如果没有就重新开启一个新的线程执行。
  • newSingleThreadScheduledExecutor()此方法返回一个ScheduledExecutorService对象,线程池大小为1,ScheduledExecutorService可以周期执行某个任务
  • newScheduledThreadPool() 此方法返回一个ScheduledExecutorService对象 但可以指定线程数量。
  1. 固定任务
public static void main(String[] args) {

        MyTesk myTesk = new MyTesk();
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
executorService.submit(myTesk);
}
executorService.shutdown();
} static class MyTesk implements Runnable { @Override
public void run() { System.out.println(System.currentTimeMillis() + Thread.currentThread().getName() + "线程执行");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

  1. 计划任务

    ScheduledExecutorService有三个重要的方法来执行计划任务

schedule(Runnable command,long delay, TimeUnit unit) ;

scheduleAtFixedRate(Runnable command,

long initialDelay,

long period,

TimeUnit unit);

scheduleWithFixedDelay(Runnable command,

long initialDelay,

long delay,

TimeUnit unit);

schedule()会在设定的延时后执行一次。

scheduleAtFixedRate()会在设定的延时(initialDelay)之后按照(period)为周期进行执行。若在下一个周期开始时当前任务未完成,则不会执行直到当前任务完成。若当前任务时间超出任务周期,则每次任务执行完就会立刻执行下一个任务。

scheduleWithFixedDelay()会在设定的延时(initialDelay)之后执行任务,任务完成后间隔(delay)进行下一次执行

如果有任务抛出异常则所有任务会全部停止执行

核心线程池内部实现

 public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
} public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}

ThreadPoolExecutor的构造方法

   public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
  • corePoolSize 指定了线程池中线程的数量
  • maximumPoolSize 指定了线程池中最大线程数量
  • keepAliveTime 当线程池中线程数量超过corePoolSize后多余线程的存活时间
  • unit keepAliveTime的时间单位
  • workQueue 任务队列被提交,但未被执行的任务的任务
  • threadFactory 线程工厂,默认即可
  • handler 拒绝策略

workQueue 任务队列

  • 直接提交队列

    由SynchronousQueue对象提供,SynchronousQueue没有容量 每一个插入操作都要等待一个删除操作,每一个删除都要等待对应的插入操作。使用SynchronousQueue提交的任务不会被真实保存,而是将新任务提交给线程执行,如果没有空闲线程就会试图创建新线程。如果进程数量已到达最大值,则执行拒绝策略。

  • 有界任务队列

    使用ArrayBlockingQueue实现,ArrayBlockingQueue(int capacity)capacity表示队列最大容量创建时必须给定当有新任务时,如果有空闲线程,就立即执行。没有则入队等待空闲线程,如果队列已满则尝试创建线程。如果线程数超过maximumPoolSize就会执行拒绝策略

  • 无界任务队列

    LinkedBlockingQueue类来实现 与有界相比,不同点在于队列不会满,只要内存资源足够可以一直添加到队列中,直到系统内存耗尽

  • 有限任务队列

    PriorityBlockingQueue可实现,它是一个特殊的无界队列,PriorityBlockingQueue可以根据任务的优先级顺序先后执行

总之线程调用逻辑

JDK并发包二的更多相关文章

  1. Java 并发编程实践基础 读书笔记: 第三章 使用 JDK 并发包构建程序

    一,JDK并发包实际上就是指java.util.concurrent包里面的那些类和接口等 主要分为以下几类: 1,原子量:2,并发集合:3,同步器:4,可重入锁:5,线程池 二,原子量 原子变量主要 ...

  2. Java并发程序设计(四)JDK并发包之同步控制

    JDK并发包之同步控制 一.重入锁 重入锁使用java.util.concurrent.locks.ReentrantLock来实现.示例代码如下: public class TryReentrant ...

  3. Java多线程--JDK并发包(2)

    Java多线程--JDK并发包(2) 线程池 在使用线程池后,创建线程变成了从线程池里获得空闲线程,关闭线程变成了将线程归坏给线程池. JDK有一套Executor框架,大概包括Executor.Ex ...

  4. Java多线程--JDK并发包(1)

    Java多线程--JDK并发包(1) 之前介绍了synchronized关键字,它决定了额一个线程是否可以进入临界区:还有Object类的wait()和notify()方法,起到线程等待和唤醒作用.s ...

  5. 3 JDK并发包

    JDK内部提供了大量实用的API和框架.本章主要介绍这些JDK内部功能,主要分为3大部分: 首先,介绍有关同步控制的工具,之前介绍的synchronized就是一种同步控制手段,将介绍更加丰富的多线程 ...

  6. 第3章 JDK并发包(三)

    3.2 线程复用:线程池 一种最为简单的线程创建和回收的方法类似如下代码: new Thread(new Runnable() { @Override public void run() { // d ...

  7. JDK并发包一

    JDK并发包一 同步控制是并发程序必不可少的重要手段,synchronized是一种最简单的控制方法.但JDK提供了更加强大的方法----重入锁 重入锁 重入锁使用java.util.concurre ...

  8. 第3章 JDK并发包(二)

    3.1.2 重入锁的好搭档:Condition条件 它和wait()和notify()方法的作用是大致相同的.但是wait()和notify()方法是和synchronized关键字合作使用的,而Co ...

  9. Java并发程序设计(五)JDK并发包之线程复用:线程池

    线程复用:线程池 一.为什么需要线程池 为了避免系统频繁地创建和销毁线程,使用线程池让线程进行复用.(即创建线程变成了从线程池中获取空闲线程,销毁线程变成了把线程放回线程池中.) 二.JDK对线程池的 ...

随机推荐

  1. 异常检测算法Robust Random Cut Forest(RRCF)关键定理引理证明

    摘要:RRCF是亚马逊发表的一篇异常检测算法,是对周志华孤立森林的改进.但是相比孤立森林,具有更为扎实的理论基础.文章的理论论证相对较为晦涩,且没给出详细的证明过程.本文不对该算法进行详尽的描述,仅对 ...

  2. 【java框架】SpringBoot(7) -- SpringBoot整合MyBatis

    1.整合MyBatis操作 前面一篇提到了SpringBoot整合基础的数据源JDBC.Druid操作,实际项目中更常用的还是MyBatis框架,而SpringBoot整合MyBatis进行CRUD也 ...

  3. SAP ABAP ALV 颜色设置(两个ALV函数例子) 列 行 单元格

    @[TOC](设置ALV颜色)# 前言淦! 要求花花绿绿的ALV ,那就淦他! 需要的参数和对应颜色放在最后.稍微改改就能用. 介绍两个常用的ALV函数实现1.REUSE_ALV_GRID_DISPL ...

  4. [Django框架之视图层]

    [Django框架之视图层] 视图层 Django视图层, 视图就是Django项目下的views.py文件,它的内部是一系列的函数或者是类,用来专门处理客户端访问请求后处理请求并且返回相应的数据,相 ...

  5. 在微信框架模块中,基于Vue&Element前端的事件和内容的管理

    在微信后台管理中,我们需要定义好菜单对应的事件管理,因为微信通过菜单触发相关的事件,因此菜单事件的响应关系,我们如果处理好,就能构建出我们的微信应用入口了.通过入口,我们可以响应用户菜单的事件,如响应 ...

  6. ELK 在 MacOS( Big Sur) 上安装与配置步骤

    ELK学习笔记 - 安装篇 目录 ELK学习笔记 - 安装篇 1. ElasticSearch 1.1 发展历史及现状 1.2 ElasticSearch 的安装 2. Logstash 2.1 Lo ...

  7. C#·对于BOM头之完全解决方案

    阅文时长 | 0.46分钟 字数统计 | 798.4字符 主要内容 | 1.引言&背景 2.使用C#写入带有/不带有BOM头的文件? 3.对于读取文件时,避免BOM头造成的异常. 4.声明与参 ...

  8. x小结:certutil -hashfile D:\1.exe MD5

    在Win7上,MD5不要使用小写,在Win10上没有这个问题 x小结:certutil -hashfile D:\1.exe MD5certutil -hashfile D:\1.exe SHA1ce ...

  9. Ansible_处理失败的任务

    一.Ansible处理任务失败 1.管理play中任务错误 1️⃣:Ansible评估任务的返回代码,从而确定任务是成功还是失败 2️⃣:通常而言,当任务失败时,Ansible将立即在该主机上中止pl ...

  10. java并发编程工具类JUC第二篇:ArrayBlockingQueue

    类ArrayBlockingQueue是BlockingQueue接口的实现类,它是有界的阻塞队列,内部使用数组存储队列元素.这里的"有界"是指存储容量存在上限,不能无限存储元素. ...