当前位置: 首页 > news >正文

Executors介绍

《阿里巴巴java开发手册》
线程池不使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样 的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
主要原因是使用Executors创建线程池不会传入这个参数而使用默认值所以我们常常忽略这一参数,而且默认使用的参数会导致资源浪费,不可取。

说明: Executors 返回的线程池对象的弊端如下:
1.FixedThreadPool 和 SingleThreadPool : 允许的请求队列长度为 Integer.MAX_VALUE ,可能会堆积大量的请求,从而导致 OOM 。
2.CachedThreadPool 和 ScheduledThreadPool : 允许的创建线程数量为 Integer.MAX_VALUE ,可能会创建大量的线程,从而导致 OOM 。


newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。

 

应用

RunnableTask.java

package com.person.threadpool;
/**
 * 任务类 :实现Runnable
 */
public class RunnableTask implements Runnable{
    private int num;
    public RunnableTask(int num){
        this.num = num;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        String threadName = Thread.currentThread().getName();
        String msg = "当前线程名 ["+threadName+"] 执行任务 [RunnableTask"+num+"] Done";
        System.out.println(msg);
    }
    
}

ExecutorsnewSingleThreadExecutorTest.java

package com.person.threadpool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorsnewSingleThreadExecutorTest {
    public static void main(String[] args) throws Exception{
        //线程池中只有一个线程,保证所有任务的执行顺序按照任务的提交顺序执行。
        //如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。
        ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();

        // 提交多个任务
        for (int i = 1; i <= 10; i++) {
            RunnableTask task = new RunnableTask(i);// 任务
            newSingleThreadExecutor.submit(task);
        }
        //主线程休眠,确保任务都执行完成再关闭线程池
        Thread.currentThread().sleep(1000);
        newSingleThreadExecutor.shutdown();// 关闭线程池,如果还是线程没有执行完成则会继续执行,只是之后不能添加新的任务
    }

}

ExecutorsnewFixedThreadPoolTest.java

package com.person.threadpool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorsnewFixedThreadPoolTest {
    public static void main(String[] args) {
        // 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
        //线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(3);

        // 提交多个任务
        for (int i = 1; i <= 10; i++) {
            RunnableTask task = new RunnableTask(i);// 任务
            newFixedThreadPool.submit(task);
        }
        newFixedThreadPool.shutdown();// 关闭线程池,如果还是线程没有执行完成则会继续执行,只是之后不能添加新的任务
    }

}

ExecutorsnewCachedThreadPoolTest.java

package com.person.threadpool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorsnewCachedThreadPoolTest {
    public static void main(String[] args) throws Exception{
        /*创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,
         *那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。
         *此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。
         */
        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
        //提交多个任务
        for(int i=1;i<=10;i++){
            RunnableTask task = new RunnableTask(i);//任务
            newCachedThreadPool.submit(task);
        }
        //主线程暂停,确保执行后面的任务时,前面的任务全部执行完成
        Thread.currentThread().sleep(4000);
        System.out.println("==========================================");
        
        //重新让线程池执行任务,可以发现 线程池中的线程被重复利用
        for(int i=11;i<=20;i++){
            RunnableTask task = new RunnableTask(i);//任务
            newCachedThreadPool.submit(task);
        }
        
        //主线程休眠,确保任务都执行完成再关闭线程池
        Thread.currentThread().sleep(1000);
        //关闭线程池
        newCachedThreadPool.shutdown();
    }

}

ExecutorsnewScheduledThreadPoolTest.java

package com.person.threadpool;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ExecutorsnewScheduledThreadPoolTest {
    public static void main(String[] args) {
        //创建一个定长线程池,支持定时及周期性任务执行
        ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(3);
        
        //延迟执行任务
        RunnableTask task = new RunnableTask(1);//任务
        newScheduledThreadPool.schedule(task, 3, TimeUnit.SECONDS); //也可以接收一个Callable实现类任务
        
        //周期性任务:延迟3秒执行第一次,每10秒执行一次,不关心上一次是否执行完成
        RunnableTask periodTask = new RunnableTask(4);//任务
        newScheduledThreadPool.scheduleAtFixedRate(periodTask, 3, 10, TimeUnit.SECONDS);
        
        //延迟3秒执行第一次任务,第一次执行完成再延迟10秒执行第二次,第二次执行完成再延迟10秒执行第三次....
        RunnableTask fixedDelayTask = new RunnableTask(8);//任务
        newScheduledThreadPool.scheduleWithFixedDelay(fixedDelayTask, 3, 10, TimeUnit.SECONDS);
         
        //newScheduledThreadPool.shutdown(); //当执行周期性任务时,不能关闭线程池,否则任务不被执行。
    }

}

 

转载于:https://www.cnblogs.com/walixiansheng/p/9612522.html

相关文章:

  • 正则表达式、re模块
  • 特殊的算术操作指令
  • jchdl - RTL Data Types
  • Python基础之for循环
  • 刚在虚拟机上装的Linux系统,ifconfig后IP地址怎么成了127.0.0.1了
  • 教你利用Python把图片转字符画!代码哆啦A梦你见过嘛?
  • MongoDB 有关实体映射具体应用及对查询的影响
  • Zabbix篇二:Linux批量安装客户端Zabbix-agent
  • 重新思考数据输入
  • EasyUI的Vue版本
  • mi家前端面经
  • cpp学习(一)环境搭建
  • Facebook 开发的 HHVM 引擎宣布停止支持 PHP
  • 面向对象:classmethod、staticmethod、property
  • 面试宝典系列-nginx的缓冲和缓存
  • 2017-09-12 前端日报
  • 2017届校招提前批面试回顾
  • C++11: atomic 头文件
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • React-Native - 收藏集 - 掘金
  • RxJS: 简单入门
  • SpiderData 2019年2月13日 DApp数据排行榜
  • spring学习第二天
  • Web设计流程优化:网页效果图设计新思路
  • XForms - 更强大的Form
  • yii2中session跨域名的问题
  • 规范化安全开发 KOA 手脚架
  • 技术:超级实用的电脑小技巧
  • 配置 PM2 实现代码自动发布
  • 批量截取pdf文件
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 问题之ssh中Host key verification failed的解决
  • 移动端解决方案学习记录
  • 原生Ajax
  • 字符串匹配基础上
  • MyCAT水平分库
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (23)Linux的软硬连接
  • (function(){})()的分步解析
  • (Redis使用系列) Springboot 使用redis实现接口幂等性拦截 十一
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (数据结构)顺序表的定义
  • (转)可以带来幸福的一本书
  • (转载)在C#用WM_COPYDATA消息来实现两个进程之间传递数据
  • (状压dp)uva 10817 Headmaster's Headache
  • **登录+JWT+异常处理+拦截器+ThreadLocal-开发思想与代码实现**
  • .apk 成为历史!
  • .Mobi域名介绍
  • .NET CLR基本术语
  • .NET Core 中的路径问题
  • .NET 读取 JSON格式的数据
  • .net 中viewstate的原理和使用
  • .net分布式压力测试工具(Beetle.DT)