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

甘肃网站建设推广服务网站排名优化查询

甘肃网站建设推广服务,网站排名优化查询,wordpress获取文章一个tag标签,个人做网站怎么备案文章目录 一、线程池概念(一)什么是线程池(二)为什么认为直接创建比在池子中取线程开销更大 二、标准库中的线程池 ThreadPoolExecutor(一)构造方法(二)七个参数含义(后四个重点掌握)(三)工厂模式1) 典型案例2) 使用工厂模式 (四)拒绝策略为什么使用线程池而不使用生产者消费者…

文章目录

  • 一、线程池概念
    • (一)什么是线程池
    • (二)为什么认为直接创建比在池子中取线程开销更大
  • 二、标准库中的线程池 ThreadPoolExecutor
    • (一)构造方法
    • (二)七个参数含义(后四个重点掌握)
    • (三)工厂模式
      • 1) 典型案例
      • 2) 使用工厂模式
    • (四)拒绝策略
      • 为什么使用线程池而不使用生产者消费者模型

一、线程池概念

回顾一下,我们最初引入线程的原因:频繁创建销毁进程,太慢了,而且开销很大
同样的,随着互联网的发展,随着我们对于性能要求更进一步~,频繁创建销毁线程,开销有些不能接受了

  • 那我们为了更高效的创建销毁线程,解决方案有两个:
  • 1.线程池
  • 2.协程(纤程,轻量级线程)

我们本篇文章重点介绍线程池

关于协程我们现在只做简单了解

  • 协程
  • Java17左右的时候,才引入到标准库中,目前在Java圈子还没有普遍使用
  • Go语言更擅长处理"并发编程"
  • 使用协程,相比于线程性能更高

线程池是一种池化技术,用于预先创建并管理一组线程,避免频繁创建和销毁线程的开销,提高性能和响应速度

(一)什么是线程池

场景:
学校新开了一家快递店,老板灵机一动,想了个与众不同的办法来经营店面,店里没有雇人,而是每次有业务,就现场找一名同学把快递送了,然后解雇同学
这就像我们平时处理一个任务,创建一个线程进行处理的模式
很快就发现了问题,每次招聘+解雇同学的成本还是很高的,所以老板指定了一个指标,业务人员扩张到3人,但是还会随着业务的扩大逐步招人,于是再有业务,如果公司没有3个人,就雇1个人去送快递,否则,只是吧业务放到一个本本上,等着3个员工空闲的时候去处理,这个就是我们的线程池模式

其实我们早就接触到了"池"的概念

  • 常量池
  • 字符串常量,在Java程序最初构建的时候,就已经准备好,等程序运行的时候,这样的常量也就加载到内存中了,省下了很大构造/创建的开销
  • 字符串常量池,线程池,进程池,内存池,数据库连接池…
  • 就像是一池子备用胎,现在虽然没有,随时要拿出来使用

简单来说线程池:把线程提前创建好,放到一个地方(类似于数组),需要用的时候,随时去取,用完了还回到池子中

(二)为什么认为直接创建比在池子中取线程开销更大

  • 操作系统中包含用户态 和 内核态
  • 一个操作系统 = 内核 + 配套的应用程序
  • 内核 中包含操作系统的各种核心功能
  • 1)管理硬件设备
  • 2)给软件提供稳定的运行环境
  • 一个操作系统,内核就是一份,一份内核要给所有的应用程序提供服务支持

在这里插入图片描述

  • 如果有一段代码是应用程序中自行完成,整个执行过程是可控的
  • 如果有一段代码,需要进入到内核中,由内核负责完成一系列工作,这个过程是不可控的,程序员写的代码干预不了
  • 因此通常认为,可控的过程要比不可控过程更高效~~

从线程池中取现成的线程,纯应用程序代码就可以完成 [可控]
从操作系统创建新线程,就需要操作系统内核配合完成 [不可控]
使用线程池,就可以省下应用程序切换到内核中运行这样的开销

二、标准库中的线程池 ThreadPoolExecutor

  • 线程池的核心方法,submit(Runnable)
  • 通过Runnable描述一段要执行的任务
  • 通过submit任务放到线程池中
  • 此时线程池里的线程就会执行这样的任务

(一)构造方法

在这里插入图片描述

(二)七个参数含义(后四个重点掌握)

在这里插入图片描述
Java的线程池,里面包含几个线程,是可以动态调整的,任务多的时候,自动扩容成更多的线程,任务少的时候 ,把额外的线程干掉,节省资源

  • 1.int corePoolSize 核心线程数
    线程池中至少有多少个线程,线程池一创建,这些线程也要随之创建,直到整个线程池销毁,这些线程才会销毁

  • 2.int maximumPoolSize 最大线程数 = 核心线程+非核心线程(自适应)
    若任务并不繁忙就会销毁,繁忙就再创建,线程也不是越多越好,毕竟线程太多会抢占资源

  • 3.long keepAliveTime 非核心线程允许空闲的最大时间
    不能这个线程一空闲下来,就直接把它销毁,因为可能下一秒就需要他干活啦,我们为他设置一个最大的摸鱼时间~~

  • 4.TimeUnit unit 是一个枚举类型的参数,作为keepAliveTime 的时间单位,是秒,分钟或者其他值
    在这里插入图片描述

  • 5.BlockingQueue workQueue : 工作队列

  • 我们可以选择使用数组/链表 指定capacity 指定是否要带有优先级/比较规则

  • 泛型为Runnable ,说明阻塞队列中的元素是一个个Runnable任务

  • 每次通过调用 submit() 方法,submit就会将任务添加到队列(阻塞队列)

  • 因为需要以阻塞队列为基础,进行数据交互,所以工作队列的类型为BlockingQueue

在这里插入图片描述

线程池本质上也是生产者消费者模型,调用submit就是在生产任务,线程池里的线程就是在消费任务

  • 6. ThreadFactory threadFactory : 线程工厂 统一的构造并初始化线程
    利用工厂模式来弥补构造方法的缺陷(无法构成重载)

(三)工厂模式

  • 是一种创建型的设计模式,提供了一种封装对象创建过程的方法
  • 工厂模式通过静态方法,将对象的创建(实例化 & 初始化) 将创建对象的过程封装好,弥补构造方法的缺陷
  • 有助于降低代码的耦合度,提高可维护性和可扩展性

1) 典型案例

在这里插入图片描述

  • 这是 C++ 和 Java共有的一个问题
  • 构造方法的名字是固定的,想要提供不同的版本,需要通过重载来实现,但是像上述情况就无法构成重载,需要借助工厂模式实现

2) 使用工厂模式

在这里插入图片描述

  • 其中 用来构造对象的静态方法(makePointByXY & makePointByRA) 称为工厂方法
  • 提供工厂方法的类(PointFactory) 称为工厂类

通过单独的类(PointFactory)提供工厂方法(makePointByXY & makePointByRA),和构造对象的类(Point)分开,这是更科学的工厂设计模式

工厂方法的核心:通过静态方法,把构造对象new的过程,各种属性初始化的过程,封装起来,提供多组静态方法,实现不同情况的构造

我们继续回到第六个参数ThreadFactory threadFactory : 线程工厂

  • 此外如果想让线程池中的线程具有其他的特性,或者想去干预这些线程的其他功能,都可以手动实现 ThreadFactory接口,重写newThread()方法
class SimpleThreadFactory implements ThreadFctory{public Thread newThread(Runnable r){return new Thread(r);}
}
  • 标准库通过这个方法,帮我们设置好线程池中基本的线程属性

  • 7.RejectedExecutionHandler handler : 拒绝策略
    整个线程池七个参数中,最重要,最复杂的

(四)拒绝策略

RejectedExecutionHandler handler
在这里插入图片描述
在这里插入图片描述

  • 1) AbortPolicy --异常,线程池可能无法继续工作

  • 当任务队列满且没有线程空闲,此时添加任务会直接抛出RejectedExecutionException异常,这也是默认的拒绝策略

  • 非但新的任务干不了,甚至之前旧的任务也干不了了~

  • 2) CallerRunsPolicy --让调用者自己干

  • 当任务队列满且没有线程空闲,此时添加任务由调用者线程即调用submit的线程来执行该任务

  • 也就是说submit整个方法里的代码,都是在这个线程中执行的

  • submit方法里,暗藏玄机~

  • 判定当前队列是否满,判定当前拒绝策略是否为CallerRunsPlicy ,如果两个判断都为true

  • submit内部就会直接调用 Runnable,run()

伪代码:

void submit(Runnable runnable){if(队列满了 && 拒绝策略为CallerRunsPlicy){runnable.run();return ;}queue.put(runnable);//若不->线程池里的一组线程来执行任务return ;
}

一个进程中会有很多个线程,假设线程池中已经有4个线程(a,b,c,d),现在来了一个新的线程X,调用submit方法
此时X调用submit,就是执行上述的伪代码逻辑,X就是调用者线程

  • 3) DiscardOldestPolicy --丢弃最老的任务,干当前给的新任务

  • 当任务队列满且没有线程空闲,会删除最早的任务,处理最新的任务

  • 4) DiscardPolicy --丢掉当前的新任务

  • 直接丢弃当前给的这个新任务,不会执行任何操作,也不会抛出异常

  • 自定义拒绝策略
    在这里插入图片描述

为什么使用线程池而不使用生产者消费者模型

在了解了拒绝策略后,再做一个扫盲,我们前面说,线程池的本质就是生产者消费者模型,那么为什么我们不直接使用生产者消费者模型

  • submit把任务添加到任务队列中,这个任务队列就是阻塞队列
  • 队列满了,再添加,就会阻塞,但是我们一般不希望程序阻塞太多
  • 对于线程池来说,入队列时发现队列满了,不会真的触发"入队列操作",不是真的阻塞,而是执行拒绝策略的相关代码
  • 如果业务逻辑中的线程调用submit就阻塞,就会使这个线程无法干别的事情了,明显不是一个好的选择
  • 线程响应用户的请求阻塞了,用户迟迟拿不到响应,直观上的现象是"卡了",其实是失败了,与其告诉我"卡了",不如直接告诉我"失败了"

线程池最大的好处就是减少每次启动,销毁线程的损耗

http://www.hkea.cn/news/948599/

相关文章:

  • 未来网站开发需求多搜索网站有哪几个
  • 网站建设 成都郑州高端网站制作
  • 快站怎么做淘客网站深圳关键词
  • 做网站时如何去掉网站横条小红书软文案例
  • 图虫南宁百度快速排名优化
  • 上城网站建设app推广文案
  • 网站建设特点宁波seo搜索引擎优化公司
  • 地产商网站建设网球新闻最新消息
  • 做爰全过程网站免费的视频谷歌seo搜索引擎
  • 怎么架设网站seo推广培训
  • 自己网站做问卷调查网页设计学生作业模板
  • 清远企业网站排名深圳网站建设系统
  • 互助平台网站建设费用卡点视频免费制作软件
  • 上海做b2b国际网站公司排名优化公司电话
  • 裙晖wordpress重庆seo整站优化
  • 乌克兰网站后缀谷歌浏览器下载电脑版
  • 建设部网站撤销注册资质的都是公职人员吗正规网络公司关键词排名优化
  • 杂志网站建设推广方案铜川网络推广
  • 网站建设后怎么搜索引擎优化解释
  • 网站建设维护 天博网络成都营销型网站制作
  • 秦皇岛北京网站建设百度广告投放电话
  • 团购做的比较好的网站营销推广ppt
  • 网站怎么做网站地图重庆网站制作公司哪家好
  • wordpress改地址后打不开seo品牌优化整站优化
  • 网页设计师证书含金量高吗百度网络优化
  • 咸阳网站开发长沙seo优化公司
  • 网站通cms国内十大搜索引擎排名
  • centos7安装 wordpress网站如何进行seo
  • 设计师灵感网站美国今天刚刚发生的新闻
  • 重庆南岸营销型网站建设公司推荐竞价sem托管