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

雪白丰腴做美妇网站外贸网站建站和推广

雪白丰腴做美妇网站,外贸网站建站和推广,网站开发pdf,福州网站制作维护服务自 JDK1.5 起,util 包提供了 ExecutorService 线程池的实现,主要目的是为了重复利用线程,提高系统效率。我们得知 Thread 是一个重量级的资源,创建、启动以及销毁都是比较耗费系统资源的,因此对线程的重复利用一种是非…

自 JDK1.5 起,util 包提供了 ExecutorService 线程池的实现,主要目的是为了重复利用线程,提高系统效率。我们得知 Thread 是一个重量级的资源,创建、启动以及销毁都是比较耗费系统资源的,因此对线程的重复利用一种是非常好的程序设计习惯,加之系统中可创建的线程数量是有限的,线程数量和系统性能是一种抛物线的关系,也就是说当线程数量达到某个数值的时侯,性能反倒会降低很多,因此对线程的管理,尤其是数量的控制更能直接决定程序的性能。

线程池的核心线程数、最大线程数该如何设置?

1、CPU密集型任务
CPU核心数+1
额外加的一个线程,是备用,还是为了更好压栈CPU
2、IO密集型任务
线程数=CPU核心数 * (1+线程等待时间、线程运行时间)
执行的IO时间越长,就可以开更多的线程
最终还是要压测
3、对于核心业务(访问频率高),可以把核心线程数设置为我们压测出来的结果,最大线程数可以等于核心线程数,或者大一点点,比如我们压测时可能会发现500个线程最佳,但是600个线程时也还行,此时600就可以为最大线程数
4、 对于非核心业务(访问频率不高),核心线程数可以比较小,避免操作系统去维护不必要的线程,最大线程数可以设置为我们计算或压测出来的结果。

阻塞队列的大小如何计算

要看每个任务平均执行多久,比如1s
100个核心线程,那么1s内能执行100个任务;如果队列大小为500,那么队列中的最后一个任务要等5s才能执行完,排队了4s。这时候要看是否可以接受任务执行耗时5s。
所以阻塞队列的大小要根据核心线程数、任务平均执行时间、可接受任务执行最大耗时决定的。

核心线程执行完任务后如何存货?

通过阻塞的方式存活。

线程池里面是非公平的

后来的任务被非核心线程执行了,先来的任务可能进入了阻塞队列

线程池执行任务的具体流程是怎样的?

在这里插入图片描述

Tomcat中的线程池

在这里插入图片描述

启动时就把核心线程创建出来了
线程池中线程数量等于最大线程数量才会入队;
有空闲线程,任务会入队

任务执行完了,非核心线程如何回收

getTask()方法返回null,然后执行processWorkerExit(w, completedAbruptly)方法
在这里插入图片描述
在这里插入图片描述

核心线程为何不会被回收

因为参数allowCoreThreadTimeOut默认为false,但是可以通过executor.allowCoreThreadTimeOut(true);将值设置为true,这样核心线程也会被回收了
在这里插入图片描述

任务发生了异常,处理任务的线程会不会被淘汰?

会被淘汰!
在这里插入图片描述
如果当前线程数等于核心线程数,怎么办?
会有一个替补线程。
在这里插入图片描述
为什么会抛出异常,感觉应该是为了拓展。抛出异常可以被线程工厂中的异常处理器(如果设置了)捕获,然后进行一些定制化的处理,如果不抛出异常的化,就无法被线程工厂中的异常处理器所捕获。
在这里插入图片描述

线程池的五种状态是如何流转的?

线程池有五种状态:
1、RUNNING:会接受新任务、会处理队列中的任务;
2、SHUTDOWN:不会接受新任务,但是会处理队列中的任务;
3、STOP:不会接受新任务、不会处理队列中的任务。并且会中断正在处理的任务(注:一个任务能不能被中断还是要看任务本身);
4、TIDYING:所有的任务都终止了,线程池也没有任务了,这样的线程池状态就会转换为TIDYING,一旦达到此状态,就会调用线程池的terminated();
5、TERMINATED:terminated()方法执行完后就会变为TERMINATED。

最后一个线程退出的时候会把线程池状态改为TIDYING,并执行terminated()方法,最后把线程池状态改为TERMINATED。
在这里插入图片描述

创建线程池

ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)
  • corePoolSize:核心线程数大小,如果提交任务时,线程池核心线程数小于corePoolSize,则会创建新线程来执行任务,即使县城池中有空闲线程;如果达到了corePoolSize,则不创建新线程。
  • maxmunPoolSize:线程池能创建的最大线程数。如果堵塞队列已满,并且当前线程数没有超过maxmiuPoolSize,就会创建新线程来执行任务;
  • keepAliveTime 空闲线程存活时间,如果当前线程数已经超过corePoolSize,并且空闲时间超过了keepAliveTime,则将这些空闲线程销毁;
  • unit 时间单位,为keepAliveTime指定时间单位
  • workQueue 阻塞队列,用于保存任务的阻塞队列
  • threadFactory 创建线程的工厂类,可以指定线程工厂为创建出的每个线程设置更有意义的线程名,如果出现问题时,方便排查;
  • handler 拒绝策略。

Java也为我们提供了一些常用的线程池类供我们直接使用,可以通过如下几种方式创建一个线程池:

Executors.newCachedThreadPool()
Executors.newFixedThreadPool(int nThreads)
Executors.newSingleThreadExecutor()
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

  • newCachedThreadPool() 允许创建的最大线程为Integer.MAX_VALUE,可能会创建大量线程,导致OOM;
  • newFixedThreadPool(int nThreads)和newSingleThreadExecutor()堵塞队列长度最大都是Integer.MAX_VALUE可能会堵塞大量任务,导致OOM

故在阿里开发手册中个,明确提出不允许用这三个线程池。

【强制】线程池不允许使用Executors创建,建议通过ThreadPoolExecutor的方式创建,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险

自定义线程池:

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20,
2 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(10));//自定义线程池

在这里插入图片描述

在这里插入图片描述
demo示例:


public class ThreadPoolDemo {public static void main(String[] args) {//自定义线程ThreadPoolExecutor executorService= new ThreadPoolExecutor(10, 20,0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(10));for (int i = 1; i <= 100; i++) {executorService.execute(new MyTask(i));}}
}class MyTask implements Runnable {int i = 0;public MyTask(int i) {this.i = i;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "线程处理第" + i + "个任务");try {Thread.sleep(2000L);//业务逻辑} catch (Exception e) {e.printStackTrace();}}
}

这个demo 10个核心线程,最多有20个线程,阻塞队列的长度为10,循环100次,向线程池提交了100个任务,执行结果如下。
在这里插入图片描述
通过打印结果知道:
1-10个任务最先执行,其次是21-30个任务,在此期间还抛出了一个异常(执行了拒绝策略),最后执行的是11-20个任务。
为什么11-20个任务是最后执行?
是因为阻塞队列中任务执行的优先级最低。

接下来看下线程池的几个核心方法:

execute

创建线程池后,通过调用该方法,即可将创建的任务交给线程池处理。

在这里插入图片描述
入队后还会再次检查下线程池的状态,如果不是RUNNING状态的话,就把刚才入队的任务移除,并执行拒绝策略。
在这里插入图片描述
入队成功后会检查线程池中线程个数,如果线程个数为0,则新建一个线程。
如果allowCoreThreadTimeOut=true,那么核心线程也会被淘汰。这里的任务是null,对应runWork()方法中的getTask(),让该线程去阻塞队列中取任务。
在这里插入图片描述

在这里插入图片描述

拒绝策略

ThreadPoolExecutor内部有实现4个拒绝策略:
在这里插入图片描述

(1)、CallerRunsPolicy,由调用execute方法提交任务的线程来执行这个任务;
(2)、AbortPolicy,抛出异常RejectedExecutionException拒绝提交任务;
(3)、DiscardPolicy,直接抛弃任务,不做任何处理;
(4)、DiscardOldestPolicy,去除任务队列中的第一个任务(最旧的),重新提交;

在项目中一般是自己实现拒绝策略

addWorker

1、根据线程池的状态和当前线程池中运行的线程数,决定能否创建新的线程
2、创建新的线程
在这里插入图片描述

在这里插入图片描述

runWorker

从这里我们可以看到执行任务的优先级
线程池的优先级包括执行提交优先级和执行优先级;队列中的执行优先级低
在这里插入图片描述

线程池优先从传入的worker对象上去拿要执行的任务,取到就执行该任务,没有取到则会调用getTask()方法从阻塞队列中获取任务。getTask方法负责从阻塞队列的对头获取任务。这些任务都是在执行execute方法时存入的。

获取要执行的任务 > 优先执行当前worker对象持有的任务,阻塞队列中的任务优先级最低。阻塞队列中的任务优先级最低是为了节省资源。
在这里插入图片描述

该方法中核心逻辑被放入到一个while循环中执行,每一次执行完task.run()方法后,都会将task置空,然后开始新一轮的循环(再次从阻塞队列中获取新的任务),这里体现了线程池线程复用的设计思想。
在这里插入图片描述

processWorkerExit

在这里插入图片描述

http://www.dtcms.com/wzjs/234082.html

相关文章:

  • 仓储服务 东莞网站建设 技术支持美国站外推广网站
  • 网站建设swot分析怎么接广告赚钱
  • wordpress博客seo优化插件优化公司治理结构
  • 如何建双注册网站网络推广有哪些方法
  • 如何把电脑改成服务器做网站如何利用seo赚钱
  • 变装丝袜说 wordpressseo外包
  • 做彩票网站需要什么网站网络营销
  • wordpress手机建站百度网页网址
  • 微商城网站建设网站优化方案范文
  • 深圳网站推广优化学seo建网站
  • 东莞横沥网站制作搜狗识图
  • 厦门服装商城网站建设营销方案范文100例
  • 延平区城乡建设和旅游局网站营销策划方案ppt模板
  • 工作服厂家无锡 帛裳服饰专业sem优化技巧
  • 摄影网站建设策划书网站关键词上首页
  • 电销卡代理加盟seo是哪个英文的简写
  • 在上海哪个网站比较好app营销
  • 比较大的做网站的公司网页设计与制作个人网站模板
  • app开发商业计划书模板win7优化大师官网
  • 北京网站排名推广北京营销公司比较好的
  • 做网站的网页设计用cdr吗宁德市人社局官网
  • 一般网站如何做防采集的网络营销有哪些例子
  • 有经验的聊城网站建设小程序开发一个多少钱啊
  • 母婴网站建设百度指数十年
  • 自助建站平台有哪些互联网营销师含金量
  • 吉水县建设局网站重庆seo技术分享
  • 个人做房产网站有哪些资料电商关键词排名优化怎么做?
  • 泰州网站建设与网页制作北京seo招聘信息
  • 怎么做自己的cms导购网站提供搜索引擎优化公司
  • 网站 管理系统常见的网络营销平台有哪些