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

可以免费发布招聘网站全网商城系统

可以免费发布招聘网站,全网商城系统,百度小程序是什么,市场监督管理局待遇如何目录 1. 线程正常的生命周期 2. 为什么要用线程池#xff1f; 3. 线程池的核心原理 4. 怎样创建线程池#xff1f; 5.线程池的代码实现 6. ThreadPoolExecutor 源码分析 7. ThreadPoolExecutor 工作原理展示#xff08;重点#xff09; 1. 线程正常的生命周期 我们知…目录 1. 线程正常的生命周期 2. 为什么要用线程池 3. 线程池的核心原理 4. 怎样创建线程池 5.线程池的代码实现 6. ThreadPoolExecutor 源码分析 7. ThreadPoolExecutor 工作原理展示重点 1. 线程正常的生命周期 我们知道线程是有生命周期的在中间不出现阻塞情况下线程从一开始的新建状态——就绪状态——运行状态——死亡状态。 2. 为什么要用线程池 在我们实际开发业务需求时往往会有很多的用户访问我们的业务如果来一个用户就创建一个线程用户结束又销毁线程如此频繁往复是非常消耗系统的性能的因此在实际开发业务时我们往往会使用线程池。 线程池的好处就是我们可以在线程池中创建多个线程当我们有业务需要用到线程时它会自动到线程池中拿取已经存在线程而不会再去创建新的线程当线程完成了相应业务后它会把使用过的线程再还到线程池中而不会销毁它等待下一次任务的执行如此一来就节省了线程的创建与销毁这一动作提高了程序的运行效率。 3. 线程池的核心原理 1我们在初始创建线程池的时候线程池是空的当然我们也可以在创建线程池的时候就定义好线程池中有几个线程。 2当我们需要用到线程时线程池会去创建新的线程对象当任务执行完毕之后它会把线程归还给线程池下次再有业务需要用到线程时不会去创建新的线程直接复用线程池中已经存在的线程。 3如果有多个任务都需要使用线程但是线程池中的线程都正在工作时而且也无法在创建多余的线程那么当钱的任务就会进行等待什么时候有空余线程任务就会再次开启。 4. 怎样创建线程池 Java已经帮我们封装好了一个关于线程池的工具类名叫 Executors我们可以根据这个工具类去创建不同类型的线程池。这里我把 Executors 的源码中所有创建线程池的方式列举下来如下图 这些以 new 开头的都是线程池的构造方法我们可以用它创建线程池。此外线程池的类型也有很多种但底层逻辑都差不多。这里我就随便拿两个当例子说一下。 1public static ExecutorsService newCachedThreadPool() 可以创建一个没有线程上限的线程池从严格意义上来说它并不算是没有上限它的上限就是 int 类型的上限大约是21亿多我们看它的源码即可得知这里它的上显示 Integer 的最大值但我们肯定不会去创建这么多的线程服务器也承受不住的。另外先记住该构造方法底层 new 了一个ThreadPoolExecutor后面会说到。 public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueueRunnable());} 2public static ExecutorsService newFixedThreadPool(int nThreads)可以创建一个有上限的线程池上限就是我们传入的参数。 源码如下所示这里也先记住该构造方法 new 了一个ThreadPoolExecutor后面会说到。 public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueueRunnable());} 5.线程池的代码实现 测试线程池如何使用我们先来定义一个线程类 // 实现 Runnable 接口 public class MyRunnable implements Runnable{// 重写 run 方法循环5次Overridepublic void run() {for (int i 0; i 5; i) { // 获取当前线程名称并打印System.out.println(Thread.currentThread().getName() ------ i);}} } 然后再定义一个线程池给它多添加几个任务 public static void main(String[] args) {// 创建一个有上限的线程池上线设置为3ExecutorService pool Executors.newFixedThreadPool(3);// 给线程池添加任务多添加几个超出它的上线 // 任务1pool.submit(new MyRunnable()); // 任务2pool.submit(new MyRunnable()); // 任务3pool.submit(new MyRunnable()); // 任务4pool.submit(new MyRunnable()); // 任务5pool.submit(new MyRunnable()); // 任务6pool.submit(new MyRunnable());} 运行 main 方法得到如下结果 可以看到在控制台中尽管我们定义了6个线程任务但线程池中却只有3个线程分别是pool-1-thread-1pool-1-thread-2pool-1-thread-3这也对应了我们创建线程池时标注的最大线程数量3而且各位也可以发现pool-1-thread-2 这个线程打印了两次for循环其实下面还有线程pool-1-thread-1与线程pool-1-thread-3打印的另外两次for循环从从我们也可以看出来虽然我们定义了6个线程任务但我们定义了一个线程池数量最大为3的线程池当任务开始时最先来的三个任务会直接使用线程池中的线程当第四个第五个第六个任务来到时它会在线程池的外边排队等待当前三个任务有人把任务做完将线程归还给线程池后其他排队等待的线程就可以取出线程池去空余的线程去完成自己的任务了 6. ThreadPoolExecutor 源码分析 刚才我们举得那两个例子特别用加粗字体说明了这两个线程池底层都是 new 了一个ThreadPoolExecutor下面我们就来看一下它的源码。 在源码中有好几个ThreadPoolExecutor 的构造方法其中有一个最重要的如下所示该方法中一共有7个参数我把它们代表的意义都列举出来。 对于 ThreadPoolExecutor 线程池来讲我们重点需要理解的有两点第一点就是这一大堆参数各自代表的含义第二就是线程池的工作原理 public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueueRunnable 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.acc System.getSecurityManager() null ?null :AccessController.getContext();this.corePoolSize corePoolSize;this.maximumPoolSize maximumPoolSize;this.workQueue workQueue;this.keepAliveTime unit.toNanos(keepAliveTime);this.threadFactory threadFactory;this.handler handler;} int corePoolSize代表线程池中的核心线程数量 int maximumPoolSize代表线程池中最大线程数量 这里我先解释一下该线程池中核心线程永远不会被销毁除非将线程池销毁除了核心线程我们还会有临时线程就好比是临时工如果我们线程池的任务过多核心线程已经忙不过来了就会有临时线程过来帮忙当临时线程空闲了一段时间之后没有接到任务它就又会被销毁。 临时线程  最大线程数量 - 核心线程数量 long keepAliveTime临时线程允许存活的时间数值如601002000等任意long类型的数都可以 TimeUnit unit这个参数与上一个是紧密联系的代表的是单位可以为秒分钟小时 如果上面 keepAliveTime 参数数值为60TimeUnit 单位为Second则表示表示空余线程可以空闲存活60秒如果TimeUnit 单位为Minutes则表示表示空余线程可以空闲存活60分钟否则就会被销毁。 BlockingQueueRunnable workQueue代表阻塞队列如果我们的核心线程都在工作时结果还有任务过来就会暂时进入到这个阻塞队列中去可以定义该队列的大小 ThreadFactory threadFactory表示我们定义的线程是从哪来的即创建线程的方式 RejectedExecutionHandler handler表示当等待队列满了临时线程也在工作状态的时候该如何处理我们可以抛出异常也可以拒绝服务等等一系列措施。 7. ThreadPoolExecutor 工作原理展示重点 刚才我大致说明了 ThreadPoolExecutor 的几个参数代表的意思下面我来举个例子让大家更好的去理解它 如下所示 现在我定义一个线程池核心线程数量定义为3临时线程数量也定义为3等待队列长度也定义为3当我们来了10个任务需要线程池去完成时我来一步步说明前提是第十个任务来了第一个任务还没有完成这里我简单描述各位应该能看懂 1第一步当来了前三个任务而且是首次接受到任务时线程池会去创建三个核心线程去处理任务123如下图所示 2第二步当来了任务456时因为核心线程都处在工作状态此时线程456 就会进入到等待队列(也叫阻塞队列)中去排队等待而不是由临时线程去处理它们如下图所示 3第三步当来了任务789时因为此时已经没有空余线程了等待队列又是满的此时线程池就会再去创建三个临时线程去处理这任务789如下图所示 4第四步当提交了第十个任务时大家可以看到此时核心线程在工作中临时线程也在工作中等待队列也满了那么此时线程池就会触发拒绝策略; 5新来的任务就会被线程池拒绝服务Java中一共有四种拒绝策略供我们选择我们可以自行设置如果不设置默认就是直接将新来的任务丢弃并抛出异常。 此外有一点需要注意这四种任务拒绝策略都是静态内部类我们直接通过类名.方法名调用即可。 一般情况下我们也不会去更改拒绝策略所以其他三种各位同学可以作为了解哦
http://www.dnsts.com.cn/news/108979.html

相关文章:

  • 网站建设前台后台教爱佳倍 北京网站
  • 电子商务网站建设与管理a卷答案美篇相册制作免费下载
  • php调用网站导航怎么弄宿迁网站建设推广
  • 个人网站域名怎么起自己做网站并让别人访问
  • 昆山 网站江西智能网站建设哪家好
  • 网站快照没了psd设计网站模板
  • php网站开发工程师面试中国六冶的网站谁做的
  • 财税营销型网站wordpress支持广告播放器
  • 陕西专业网站开发联系电话wordpress好主题
  • j建设网站备案流程做中英文网站要注意什么
  • 爱网是什么网站重庆建设工程质量信息网
  • 网站备案编号dede网站建设很卡
  • 广东微信网站建设价格什么是空壳网站
  • 中能建设集团电子商务网站网站开发类合同范本
  • 做陶瓷公司网站网站关键词快排名
  • 南通微信网站开发appstore免费下载
  • 计算机专业论文网站开发网站建设的平台
  • 无锡装修网站企石仿做网站
  • 汽车网站建设公司哪家好做外贸没有网站需要
  • 智能建站官网有哪些公司网站建设比较好
  • 高端的网站推广太原专门做网站
  • 莆田哪里有做网站的公司网站快速备案
  • 珠海市网站建设哪家好重庆网站备案需要几天
  • 比较好的手机网站短视频推广引流
  • 昆明做网站建设技巧公司济南网站seo
  • 西山网站建设网站建设伍金手指下拉8
  • 创新的网站建设有哪些购物平台
  • 网站建设要用什么软件做网站用什么配置的vps
  • 九宫格网站模板做网站运营的女生多吗
  • 自己设置网站怎么做正邦设计创始人