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

低价做网站远洋国际建设有限公司网站

低价做网站,远洋国际建设有限公司网站,网络推广网站公司推荐,嵌入式培训学校线程诞生的意义#xff0c;是因为进程的创建/销毁#xff0c;太重了#xff08;比较慢#xff09;#xff0c;虽然和进程比#xff0c;线程更快了#xff0c;但是如果进一步提高线程创建销毁的频率#xff0c;线程的开销就不能忽视了。 这时候我们就要找一些其他的办法… 线程诞生的意义是因为进程的创建/销毁太重了比较慢虽然和进程比线程更快了但是如果进一步提高线程创建销毁的频率线程的开销就不能忽视了。 这时候我们就要找一些其他的办法了。 有两种典型的办法可以进一步提高这里的效率 1 协程 轻量级线程相比于线程把系统调度的过程给省略了变成由程序员手工调度 当下一种比较流行的并发编程的手段但是在Java圈子里协程还不够流行GO和Python用的比较多 2线程池Java用的 接下来我们就来介绍一些线程池  线程池 优化频繁创建销毁线程的场景  首先我们先来了解一下什么是池 池  假设一个美女有很多人追美女就从这些人里面挑了一个她最喜欢的交往交往一段时间之后美女她腻了她想换一个男朋友那她接下来就要干两件事 1想办法和这个男的分手需要一些技巧比如挑他毛病作 之类的 2再找一个小哥哥培养感情然后交往  但是这样的效率就比较低啦有没有什么办法来提高一些效率呢 当然有只有美女在和前一个交往的时候和另一个或多个小哥哥搞暧昧养把他们都放到自己的鱼塘里那和上一个分手下一个男朋友来的就很快了。  我们还是只做了两步只是把第二步提前了。  那“鱼塘”里的这些人我们通常叫他们 —— “备胎”  那这个“鱼塘” 就 可以看成 “池” 来放“备胎” 同样的线程池就是在使用第一个线程的时候提前把 2345...(多个)线程创建好相对于前面的培养感情那后续我们想使用新的线程的时候就不必重新创建了直接拿 池 里的线程用就行了。此时创建线程的开销就被降低了 为什么从池子里取的效率比新创建线程效率高 这是因为从池子里取 这个动作是存粹的 用户态 的操作而创建新的线程这个动作则是需要 用户态 内核态 相互配合完成的操作。 内核态 和  用户态  如果一段程序是在系统内核中执行的此时就称为“内核态” 如果不是则称为“用户态” 操作系统是由 内核 配套的应用程序 构成的 内核系统最核心的部分 创建线程操作就需要调用系统 api进入到内核中按照内核态的方式来完成一系列动作。 内核态的操作要比 纯用户态的操作开销要更大 至于为什么我们来举一个例子解释一下 银行办业务的例子  首先这个来办理业务的人他不能 进入柜台后面只能在大厅里 这个人想来办张银行卡需要身份证复印件但是这个人他忘带了那此时柜台的服务人员就给了他两个选择 1把身份证给她她去帮他复印 2大厅的角落有一个自助复印机他可以去那里自己复印  那这两个选择中的第二个自己复印就是纯 用户态操作这个人可以立即去复印完事后立即回来办理业务整个过程非常利落非常可控 但是如果交给 柜台的服务人员第一个选择这个过程就涉及到 内核态 操作了那此时你把东西交给他俩你也不知道柜员消失之后去做了那些事情也不是的她啥时候回来整个过程是不可控的。 操作系统内核是要给所有的进程提供服务的当你要创建线程的时候内核虽然会帮你做但是做的过程中难免也要做一些其他的事情。那在你这边的结果就不是那么可控。 上述就是内核态 和 用户态的区别 。 Java标准库中的线程池   线程池的创建  我们发现了线程池这个对象不是我们直接 new 的而是通过一个专门的方法返回了一个线程池的对象。  这种写法就涉及到了 “工厂模式”校招常考的设计模式和上一篇介绍的 单例模式 并列  工厂模式 工厂模式的作用  通常我们创建对象 都是使用 newnew 关键字就会触发 类的构造方法但是构造方法存在一定的局限性。 “工厂模式” 就是给 构造方法填坑的。  那 “工厂模式” 具体是填的什么 坑 呢我们举一个例子 假设 考虑 一个类来表示平面上的点 然后我们给这个类提供构造方法 第一个构造方法  期待使用笛卡尔坐标系来构造对象。  第二个构造方法 使用极坐标来构造对象  但是编译失败了。  原因 很多时候我们希望构造一个对象可以有多种构造方式 。那多种方式我们就需要使用多个版本的构造方法来分别实现但是构造方法要求方法的名字必须是类名不同的构造方法 只能通过 重载 的方式来区分了而重载又要求 参数类型 或 个数 不同。 而上面的两个构造方法 很明显没有构成 重载当然会编译失败。  这就是 构造方法的局限性 。 那“工厂模式”就能解决上述问题 使用普通的方法代替构造方法完成初始化工作普通的方法就可以使用方法的名字来区分了。也就不受 重载的规则制约了。 工厂模式实践  在实践中我们一般单独 搞一个类然后给这个类搞一些静态方法由这些静态方法负责构造出对象  伪代码  class PointFactory {public static Point makePointByXY(double x, double y) {Point point new Point();point.setX(x);point.setY(y);return p;}public static Point makePointByRA(double r, double a) {//和上边类似} } class Demo {public static void main(String[] args) {//使用 Point p PointFactory.makePointByXY(10,20); } }上述介绍之后我们就知道了为啥 线程池 的 对象我们不直接 new 了 这种方法就是 工厂模式  不同的几种线程池  第一种  此时构造出的线程池对象有一个基本特点线程数目是能够动态适应的。 cached: 缓存用过之后不着急释放先留着以备下次使用。 也就是说随着往线程池里添加任务这个线程池中的线程会根据需要自动被创建出来创建出来之后也不会着急销毁会在池子里保留一定的时间以备随时再使用。 除了上边的线程池我们还有其他的线程池 第二种 这个方法就需要我们指定 创建几个线程线程个数是固定的 Fix固定 第三种 只有单个线程的线程池  第四种 类似于 定时器 只是 不是只有一个 扫描线程 负责执行任务了而是有多个线程执行时间到的任务. 第一种和第二种常用 上述这几个工厂方法生成的线程池本质上都是对 一个类进行的封装 ——  ThreadPoolExector ThreadPoolExector 这个类的功能十分丰富它提供了很多参数标准库中上述的几个工厂方法其实就是给这个类填写了不同的参数来构造线程池。  ThreadPoolExector 的使用方式 ThreadPoolExector 的核心方法 1.构造方法 2.注册任务添加任务 注册任务(简单)submit  ⁜⁜ 构造方法⁜⁜【经典面试题】 构造方法中的参数很多且重要  我们打开Java文档     Overview (Java Platform SE 8 ) (oracle.com) 打开这个包  juc —— 这个包里放的试和 “并发编程” 相关的内容Java中并发编程最主要的体现形式就是多线程) 点进这个包然后往下找  然后我们直接翻到构造方法 上面的四个构造方法都差不多就是参数个数 不一样第四个 参数最多能够涵盖上述的三个版本。  所有我们重点看第四个构造方法  这一组参数描述了线程池中线程的数目  这个线程池里的线程 的数目试可以动态变化的 变化的范围就是【corePoolSize, maximumPoolSize】 那 “核心线程”  和 “最大线程” 如何理解呢 如果把一个线程池理解为一个公司此时公司里有两类员工         1.正式员工         2.实习生 那正式员工的数目就是核心线程数正式员工 实习生的数目就是最大线程数 正式员工和实习生的区别 正式员工允许摸鱼不会因为摸鱼被公司开除有劳动法罩着。 但是实习生不允许摸鱼如果这段时间任务多了此时就可以多搞几个实习生去干活如果过段时间任务少了并且这样的状态还持续了一定时间那空闲的实习生就可以裁掉了。 这样做既可以满足效率的要求又可以避免过多的系统开销 。 ps  使用线程池需要设置线程的数目数目设置多少合适  一定不是一个具体的数字因为在接触到实际的项目代码之前这个数目是无法确定的 一个线程 执行的代码主要有两类 1.cpu 密集型代码里主要的逻辑是在进行 算术运算/逻辑判断。 2.IO 密集型代码里主要进行的是IO操作。 —— 假设一个线程的所有代码都是 cpu 密集型代码这个时候线程池的数量就不应该超过N就算设置的比N大此时也无法提高效率因为cpu吃满了。 —— 假设一个线程的所有代码都是 IO 密集型代码这个时候不吃cpu此时设置的线程数就可以是超过N一个核心可以通过调度的方式来并发执行 上述我们就知道了代码不同线程池的线程数目设置就不同我们无法知道一个代码具体多少内容是cpu密集多少内容是IO密集。所以我们无法确定 数目设置多少合适。 正确做法使用实验的方式对程序进行性能测试测试的过程中尝试修改不同的线程池的线程数目看那种情况更符合要求。 这一组参数描述了允许实习生摸鱼的时间实习生不是 一摸鱼就马上被开除 这个参数的意思是 阻塞队列 用来存放线程池里的任务。 可以根据需要灵活设置这里的队列是啥比如需要优先级 就可以设置 PriorityBlockingQueue 如果不需要 优先级并且任务数目是相对恒定的可以使用 ArayyBlockingQueue如果不需要优先级并且任务数目变动比较大就可以用 LinkedBlockingQueue 这个参数就是 工厂模式的体现 此处使用 ThreadFactory 作为 工厂类 由这个类负责创建线程 使用工厂类来创建线程主要是为了在创建线程的过程中对线程的属性做出一些设置。  如果手动创建线程就得手动设置这些属性就比较麻烦使用工厂方法封装一下就更方便。  下面这个参数是最重要的  是线程池的拒绝策略 一个线程池能容纳的任务数量有上限当持续往线程池里添加任务的时候一旦达到了上限还继续添加会出现什么效果 拒绝策略就是来解决这个问题的 不同的拒绝策略有不同的效果。 上面的这四个就是不同的拒绝策略 如果队列满了再添加就直接抛出异常  新添加的任务由添加任务的线程负责执行  丢弃最老的任务  丢弃当前新加的任务  实现一个简单的线程池 这个代码比较简单就不多说了代码里都有注释  import java.awt.*; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;/*** Author: iiiiiihuang*/ public class ThreadPool {//任务阻塞队列private BlockingQueueRunnable queue new ArrayBlockingQueue(4);//通过这个方法把任务添加到队列中public void submit(Runnable runnable) throws InterruptedException {//此处的拒绝策略相当于第五种策略阻塞等待下策queue.put(runnable);}//构造方法public ThreadPool(int n) {//创建出n个线程负责执行上诉队列中的任务for (int i 0; i n; i) {Thread t new Thread(() - {//让这个线程从队列中消费任务并执行try {//取出Runnable runnable queue.take();//执行runnable.run();} catch (InterruptedException e) {throw new RuntimeException(e);}});t.start();}} } 关注点赞评论收藏支持一下╰(*°▽°*)╯╰(*°▽°*)╯
http://www.sczhlp.com/news/196005/

相关文章:

  • 培训视频网站北京网站设计制作过程
  • 他达拉非功效与作用主要会有哪些seo搜索引擎优化方法
  • 网站做细分领域淄博三合一网站开发
  • 精确率
  • “[GESP202509 五级] 有趣的数字和”分块做法
  • 网站开发师是属于IT主体职业太原网页设计公司是销售吗
  • 域名备案网站名称个人备案可以做影视网站吗
  • 胶南网站建设小红书小程序入口
  • 开一个网站建设公司好wordpress 没有保存
  • 肥城做网站青岛+网站建设
  • 淘宝客手机网站开发dw如何制作一个搜索栏
  • 钦州做网站vip解析网站怎么做
  • 高端网站建设企业网站建站咨询管理
  • 哪些网站能够免费做公考题网站建设中如何使用字体
  • 网站必须要求备案吗现在的网站使用frameset做吗
  • 网站硬件防火墙丹阳seo公司
  • 秦皇岛做网站哪家好佛山电子商务网站建设
  • 奉化建设网站域名购买平台有哪些
  • 如何在年报网站上做遗失公告做citation的网站
  • 怎么为网站做外链网站建设的考虑
  • 网站外包 博客美食网站建设合同范例
  • 自建网站做网上超市可行吗做网络销售感觉自己是骗子
  • 简述网站制作的过程阿里云wordpress 备份数据
  • 那个网站做直播好永兴县网站建设哪个好
  • 学校网站建设教程合肥网络关键词排名
  • 网站上展示手机页面是怎么做的公司做网站域名的好处
  • 店铺推广和网站优化一起做wordpress用户搜索次数
  • 做网站广告语买做指甲的材料在哪个网站
  • 建设网站什么软件比较好wordpress模板恢复
  • 网站建设概括找个网页公司做网站