ARTS-11(动态规划、线程池解析、Feign原生接口调用、好用工具推荐)
Algorithm
动态规划思路及解题
Review
线程池的使用
1)、多线程的好处
- 提升资源利用率
- 提高程序处理效率:例如对执行顺序不敏感的任务,可以交由多个线程进行并行处理
- 减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
- 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。
- 线程池作用就是限制系统中执行线程的数量,用线程池控制线程数量,其他线程排 队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一个新任务需要运行时,如果线程池 中有等待的工作线程,就可以开始运行了;否则进入等待队列。
2)、线程池的创建
- 实现Runable接口并重写run()方法
- 实现Callable接口并重写call()方法
- 继承Thread类并重写run()方法
- 使用线程池,将任务交付给线程池,由线程池按照指定的方式进行调度,创建线程主要有以下两种方式:
a、直接创建ThreadPoolExecutor实例
b、 使用Executors创建常见的线程池类型(不推荐使用)
直接创建ThreadPoolExecutor实例
ThreadPoolExecutor的四种构造函数:
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue) {}public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory) {}public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) {}public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,
long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler){}
参数说明:
corePoolSize:核心线程数。在创建线程池之后,默认情况下线程池中并没有任何的线程,而是等待任务到来才创建线程去执行任务,当线程池中的线程数目达到 corePoolSize后,新来的任务将会被添加到缓存队列中,也就是那个workQueue,除非调用ThreadPoolExecutor#prestartAllCoreThreads()
方法或者是 ThreadPoolExecutor # prestartCoreThread()
方法(从这两个方法的名字就可以看出是预创建线程的意思,即在没有任务到来之前就创建corePoolSize个线程或一个线程)。
maximumPoolSize:允许在线程池中存活的最大线程数量,当线程池中的线程数等于 corePoolSize 并且 workQueue 已满,这时就要看当前线程数是否大于 maximumPoolSize,如果小于maximumPoolSize 定义的值,则会继续创建线程去执行任务, 否则将会调用去相应的任务拒绝策略来拒绝这个任务。另外超过 corePoolSize的线程被称做"Idle Thread", 这部分线程会有一个最大空闲存活时间(keepAliveTime),如果超过这个空闲存活时间还没有任务被分配,则会将这部分线程进行回收。
keepAliveTime:现成的最大空闲时间,当超过这个时间后线程会被终止
unit:keepAliveTime的单位
workQueue:用户保存已被提交尚未被执行的任务
- ArrayBlockingQueue //基于数组的先进先出队列,此队列创建时必须指定大小;
- LinkedBlockingQueue //基于链表的先进先出队列,如果创建时没有指定此队列大小,则默认为Integer.MAX_VALUE
- synchronousQueue //这个队列比较特殊,它不会保存提交的任务,而是将直接新建一个线程来执行新来的任务。
threadFactory:线程工厂。用来为线程池创建线程,当我们不指定线程工厂时,线程池内部会调用Executors.defaultThreadFactory()创建默认的线程工厂,其后续创建的线程优先级都是Thread.NORM_PRIORITY。如果我们指定线程工厂,我们可以对产生的线程进行一定的操作。
handler:拒绝执行策略。当线程池的缓存队列已满并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略
实际运用
ThreadPoolExecutor executor = new ThreadPoolExecutor(5,10,200,TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(5));
//public void execute(Runnable command)
executor.execute(task);private ThreadPoolExecutor jobExecutor = new ThreadPoolExecutor(10, 10, 1, TimeUnit.MINUTES,new ArrayBlockingQueue<>(1000),r -> new Thread(r, "schedule-worker-" + jobWorkerCount.incrementAndGet()),(r, executor) -> {r.run();ScheduleAlarmUtil.alarm("定时任务线程池溢出",r + " \nqueue.size=" + executor.getQueue().size(),"schedule-pool-reject-" + DateFormatUtils.format(new Date(), "yyyyMMdd"));});
java通过Executors线程工具类创建线程池
Java通过Executors提供四种线程池,分别为:
1、newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。其工作线程的创建数量几乎没有限制。maximumPoolSize=Integer.MAX_VALUE
2、newFixedThreadPool 创建一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池对列中。
其任务队列的长度基本是无限的,具有内存溢出的风险new LinkedBlockingQueue()
3、newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
其工作线程的创建数量几乎没有限制(maximumPoolSize=Integer.MAX_VALUE),任务队列长度也是基本是无限的,具有内存溢出的风险
4、newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
其任务队列的长度基本是无限的,具有内存溢出的风险new LinkedBlockingQueue()
public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());}public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());}public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {return new ScheduledThreadPoolExecutor(corePoolSize);
}
public ScheduledThreadPoolExecutor(int corePoolSize) {super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,new DelayedWorkQueue());
}public static ExecutorService newSingleThreadExecutor() {return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));}
实际使用
ScheduledExecutorService pool = Executors.newScheduledThreadPool(5);
TaskC task = new TaskC();
ScheduledFuture<String> future = pool.schedule(task,1,TimeUnit.SECONDS);
Tips
原生Feign调用接口的方法
1、maven引入
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-core</artifactId><version>10.1.0</version><scope>compile</scope>
</dependency>
<dependency><groupId>com.netflix.feign</groupId><artifactId>feign-gson</artifactId><version>8.4.1</version><scope>compile</scope>
</dependency>
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId><version>10.1.0</version>
</dependency>
2、实际使用
public interface xxxClient {@RequestLine(value = "GET /xx/xxx/xxx/getxxx?userId={UserId}¤tPage={currentPage}&pageSize={pageSize}")@Headers("Authorization:Basic {token}")public xxxResponseEntity<xxxPage<String>> getDatabase(@Param("token") String token,@Param("userId") String userId, @Param("currentPage") Integer currentPage, @Param("pageSize") Integer pageSize);}
public void method{private BDPClient getxxxClient(){return Feign.builder().encoder(new GsonEncoder()).decoder(new GsonDecoder()).target(xxxClient.class, cdhHost);}private String getDefaultToken(){return new String(Base64.encodeBase64(cdhToken.getBytes()));}public xxxResponseEntity<xxxPage<String>> getDatabase(String userId, Integer currentPage, Integer pageSize) {return getxxxClient().getDatabase(getDefaultToken(), userId, currentPage, pageSize);}
}
Share
分享一些程序员好用工具:
1、截图工具:snipaste,使用简单,贴图方便
2、desktopcal桌面日历是一款桌面工具,通过desktopcal桌面日历,你可以很方便的记录事项、管理日程,让你在每次看到桌面时就能及时知道制定的计划完成度等
待更。。。
ARTS-11(动态规划、线程池解析、Feign原生接口调用、好用工具推荐)相关推荐
- 【JUC并发编程11】线程池
文章目录 线程池 11.1 线程池概述 11.2 线程池架构 11.3 线程池使用方式 11.4 线程池底层原则 11.5 线程池的七个参数 11.6 线程池底层工作流程 11.7 自定义线程池 线程 ...
- 线程池解析(三)——Worker源码解析
相关文章 线程池解析(一)--概念总结 线程池解析(二)--execute.addWorker源码解析 线程池解析(三)--Worker源码解析 线程池解析(四)--submit源码解析(Runnab ...
- 1、基于Feign的接口调用概述
我们通过一个例子来解析"基于Feign的接口调用" 1.示例概述 图中有三个服务app-a.app-b.app-a-api app-a-api 是 app-a 服务的接口规范,里面 ...
- 使用C++11封装线程池ThreadPool
2019独角兽企业重金招聘Python工程师标准>>> 读本文之前,请务必阅读: 使用C++11的function/bind组件封装Thread以及回调函数的使用 Linux组件封装 ...
- 面试必备:Java线程池解析
点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 来源:https://juejin.im/post/5d1882b1f265da1ba84aa ...
- vue开发app项目,涉及原生接口调用,用hbuilder打包
使用vue开发app项目,怎么使用手机的原生功能,以获取手机的相册,调用摄像头为例. 这里使用的是hbuilder打包. 第一步: 定义一个vue组件,代码如下: <template>&l ...
- Java多线程(7)--线程池创建线程
经常创建和销毁.使用量特别大的资源,比如并发情况下的线程,对性能影响很大. 提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中,可以避免频繁创建销毁.实现重复利用. 使用线程池好处: ① ...
- c++11线程池的实现原理及回调函数的使用
关于线程池 简单来说就是有一堆已经创建好的线程(最大数目一定),初始时他们都处于空闲状态.当有新的任务进来,从线程池中取出一个空闲的线程处理任务然后当任务处理完成之后,该线程被重新放回到线程池中,供其 ...
- 从源码学习线程池的使用原理及核心思想解析
文章内容引用自 咕泡科技 咕泡出品,必属精品 文章目录 1为什么要使用线程池 2几种常用线程池介绍 3从初始化开始 4执行任务execute 5添加线程addWorker 6运行新的线程runWork ...
最新文章
- (转)[Android] 利用 ant 脚本修改项目包名
- C#中巧用Lambda进行数据的筛选查询等处理
- ACL 2018论文解读 | 基于排序思想的弱监督关系抽取选种与降噪算法
- python csdn博客_利用Python抓取CSDN博客
- 《JavaScript设计模式与开发实践》模式篇(3)—— 代理模式
- MySQL 纯insert_MySQL使用INSERT插入多条记录
- MySQL千万级别大表如何优化?
- leetcode之二叉树的层序遍历
- Django no such table: django_session错误解决办法
- python spark社区_Spark中文python文档
- 样机|UI大佬用的样机,都在这里哦!
- 面向对象编程——2.细致了解
- 压测工具ab的安装(mac环境)
- 2017-9-22 NOIP模拟赛[xxy][数论]
- 牛客--两种排序方法
- 阿里二面惨败,痛哭流涕狂刷 1000+ 面试题,成功面上五面上岸滴滴
- echarts地图api series_ECharts地图绘制和钻取简易接口详解
- Android 3D 魔方游戏的设计与开发
- 第一节:linux 开发AI算法以及libtorch部署算法详细教程-环境搭建
- 关于.Net与J2EE的比较,到底用微软平台还是Java平台的问题
热门文章
- 相似矩阵的判断(必看)
- iOS应用处于前台、后台、应用被杀掉场景-收到远程推送内容进行收款语音播报;
- python 使用字节流bytes格式读取文件转为int格式,再转为0,1字符串格式
- 图_SimpleGraph
- 微信小程序 账号密码 和 手机号 验证码 登录
- Ajax是什么以及Ajax交互原理(详,图文并茂,原理篇)
- java 部分和_java中的部分关键字和用法
- 【python制作小游戏】能用工具尽量别耗时间,速战速决,见识新的天空——开心消消乐
- 定论——软件开发的方法论探讨
- java-net-php-python-jspm驴友自助旅游管理系统计算机毕业设计程序