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

如何查询公司做没做网站/seo的作用有哪些

如何查询公司做没做网站,seo的作用有哪些,wordpress 企业小程序,网站标题是关键词吗为什么需要线程池:线程创建、销毁 线程的建立和销毁,维护一个线程池处理多任务,更加有效利用cpu。那么主要是浪费那些资源呢?我们来分析创建一个线程的过程 上面已经提到了,创建一个线程还要调用操作系统内核API。为了…

为什么需要线程池:线程创建、销毁

线程的建立和销毁,维护一个线程池处理多任务,更加有效利用cpu。那么主要是浪费那些资源呢?我们来分析创建一个线程的过程
上面已经提到了,创建一个线程还要调用操作系统内核API。为了更好的理解创建并启动一个线程的开销,我们需要看看 JVM 在背后帮我们做了哪些事情:

  • 它为一个线程栈分配内存,该栈为每个线程方法调用保存一个栈帧
    每一栈帧由一个局部变量数组、返回值、操作数堆栈和常量池组成
    一些支持本机方法的 jvm 也会分配一个本机堆栈
  • 每个线程获得一个程序计数器,告诉它当前处理器执行的指令是什么
  • 将与线程相关的描述符添加到JVM内部数据结构中
  • 线程共享堆和方法区域
  • 系统创建一个与Java线程对应的本机线程
    Java 中的线程模型是基于操作系统原生线程模型实现的,也就是说 Java 中的线程其实是基于内核线程实现的,线程的创建,析构与同步都需要进行系统调用,而系统调用需要在用户态与内核中来回切换,代价相对较高,线程的生命周期包括「线程创建时间」,「线程执行任务时间」,「线程销毁时间」,创建和销毁都需要导致系统调用。

这段描述稍稍有点抽象,用数据来说明创建一个线程(即便不干什么)需要多大空间呢?答案是大约 1M 左右。如果每个用户请求都新建线程的话,1024个线程就占用了1个G的内存,看来不对线程进行管理隐患很大,于是提出了线程池的概念。

线程池的使用

一般我们都会用Executors来创建线程,这是一个线程池工厂类,调用各类方法可以获得相应的线程池。线程池基本都是利用ThreadPoolExecutor类来创建的,类似Executors.newFixedThreadPool的内部实现代码:

return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());  # 队列大小是 Integer.MAX_VALUE

我们根据入参顺序来刨解:

  • corePoolSize:线程的数量
  • maximumPoolSize:最大线程数量
  • keepAliveTime:线程存活的时间数量
    这里要特殊说明,只有当打活跃的线程数大于corePoolSize,keepAliveTime才会起作用,线程存活的时间超过keepAliveTime就会回收线程,也就是将线程销毁。
  • unit :存活时间单位,是秒还是分钟还是小时
  • workQueue:任务队列,用来存储排队执行的任务

通过参数来理解线程池的大致流程:

  • 1、新来任务,当前线程数量小于corePoolSize,新建线程执行任务
  • 2、线程数量等于corePoolSize,把任务放到workQueue
  • 3、workQueue满了,线程数量小于maximumPoolSize,新建线程执行任务
  • 4、workQueue满了,线程数量等于maximumPoolSize,拒绝任务
  • 5、workQueue任务越来越少,线程不停的从里面拿任务执行。
  • 6、workQueue空了,有线程空闲并且线程数量大于corePoolSize,根据keepAliveTime来销毁多余的线程,一直到线程数量等于corePoolSize
  • 7、没有任务,当前活跃的线程数量 == corePoolSize ,不会被销毁

Excutors工厂类 创建线程池

  • newFixedThreadPool
    corePoolSize 等于 maximumPoolSize的线程池,固定的线程数大小。
    缺点:任务队列是LinkedBlockingQueue,最大任务数是 Integer的最大值,是个坑,积累的任务数非常多
  • newCachedThreadPool
    缺点:maximumPoolSize最大为 Integer.MAX_VALUE,容易造成堆外内存溢出,SynchronousQueue入队出队必须同时传递,因为这个线程池线程最大,也不需要存储队列任务
  • newSingleThreadExecutor
    单个线程的线程池,只有一个线程,处理慢一点而已,但确保线程是有序处理任务。
    缺点:LinkedBlockingQueue无边界的队列任务,处理太慢,都不会感知到。
  • newScheduledThreadPool
    支持定时及周期性的任务执行的线程池,maximumPoolSize的值是Integer.MAX_VALUE;DelayedWorkQueue是无界的,因此maximumPoolSize是无效的。处理延迟主要是靠DelayedWorkQueue。
    缺点:线程数量最大值太大,队列无界限。

阿里巴巴开发手册上:【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

因为它们或多或少的有一些问题,很容易在实际生产中引发事故,我们应该了解他们的缺点,分别来对应使用在不同的场景中,特别是自己手动创建线程池,我们应该了解这些参数该如何设置。

  • 无界队列 容易导致任务不停的追加,内存不被回收,可能 OOM
  • 线程池数目无限大,容易造成堆外内存溢出
  • 有界队列:ArrayBlockingQueue:基于数组的队列,创建时需要指定大小。

拒绝策略:

  • ThreadPoolExecutor.AbortPolicy (默认的执行策略)丢弃任务,并抛出 RejectedExecutionException 异常。
  • ThreadPoolExecutor.CallerRunsPolicy:该任务被线程池拒绝,由调用 execute 方法的线程执行该任务。
  • ThreadPoolExecutor.DiscardOldestPolicy :抛弃队列最前面的任务,然后重新尝试执行任务。
  • ThreadPoolExecutor.DiscardPolicy,丢弃任务,不过也不抛出异常。

如何保持线程复用

其实开启一个线程后,再线程的run 方法中 写一个循环,执行一个任务后就从队列中获取任务对象Worker,Worker对象是线程池定义的对象,一个Worker对象中都有一个线程,任务Worker的个数就表明线程的个数,不过代码里没有利用Worker集合的大小来做判断,而是利用了AtomicInteger对象来控制线程数量。同时为了保证避免线程的销毁,线程池稳定运行之后一般都会保证corePoolSize大小的线程是活跃的,不会主动销毁。

每一个任务 也都是一个Runnable对象

在线程池里每一个任务也都是一个可执行的Runnable对象,在线程的run 方法中执行 task.run()方法来执行对象,这样就执行了一个任务,要记住这里不是start方法,start方法是起一个线程来执行,想当于额外的起线程来执行代码,这样就不是线程复用,所以执行run方法执行线程的内容。

为何设计keepAliveTime 但又不销毁全部线程

主要是线程池要保证一定的线程活跃,所以不能全部销毁线程,避免频繁的创建和销毁,如果认为线程池线程一直不销毁占用系统字段,其实可以通过corePoolSize的大小来控制活跃的线程数量。

如何销毁线程

利用阻塞队列来实现,代码如下:

private Runnable getTask() {boolean timedOut = false; // Did the last poll() time out?for (;;) {int c = ctl.get();int rs = runStateOf(c);// Check if queue empty only if necessary.if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {decrementWorkerCount();return null;}int wc = workerCountOf(c);// Are workers subject to culling?boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;if ((wc > maximumPoolSize || (timed && timedOut))&& (wc > 1 || workQueue.isEmpty())) {if (compareAndDecrementWorkerCount(c))return null;continue;}try {Runnable r = timed ?workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :workQueue.take();if (r != null)return r;timedOut = true;} catch (InterruptedException retry) {timedOut = false;}}}

workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) ; 这里面keepAliveTime 是阻塞队列等待的时间,如果超过这个时间还没有任务,就返回null,这样work对象就执行结束了,线程就执行结束,自动就销毁掉了。调用关系:

runWorker()  - - >  getTask()

插入任务、获取任务

在超出核心线程数目后,就不再起线程,而是通过添加到阻塞队列里,暂缓任务,等有空闲线程再拉取任务。

  • 插入 :offer
  • 获取 :take poll 两个方法

参考博客

线程池位运算
手撕ThreadPoolExecutor线程池源码
为什么都说线程切换开销小于进程呢?
【搞定面试官】你还在用Executors来创建线程池?会有什么问题呢?

http://www.jmfq.cn/news/5091229.html

相关文章:

  • php教育视频网站开发/官网seo是什么意思
  • 建设智能网站/肇庆网络推广
  • 房地产网站源码/娄底地seo
  • 自建网站的流程/网络营销seo是什么意思
  • 河源网站建设1993seo/google搜索app下载
  • 法院 公开网站建设情况/营销计划怎么写
  • 衢州品牌网站设计/茂名seo顾问服务
  • 柳州建设局网站/前端seo怎么优化
  • 驻马店哪里做网站/网站推广排名服务
  • 网站制作高手/seo查询官方网站
  • php 简单购物网站/河北优化seo
  • 中国城乡与建设部网站/seo具体怎么优化
  • 做网站都有那些步骤/关键词自动优化
  • 网站开发实用技术介绍/怎么优化
  • 网络科技官网/百度seo排名优
  • wordpress登录注册页面/seo建设招商
  • 推荐十个国外网站/天津抖音seo
  • 佛山正规网站建设报价/重庆森林讲了什么故事
  • web如何做网站/seo关键词优化排名外包
  • 上海羚凯网站建设/收录网站查询
  • wordpress to zblog/山西网络营销seo
  • 做2手物品通过网站去卖掉好做吗/seo优化排名百度教程
  • 从做系统网站的收藏怎么找回/茶叶网络推广方案
  • 高端网站建设公司哪家服务好/泰州网站优化公司
  • 寻找专业网站建设/口碑营销案例简短
  • 保定市做网站的电话/重庆关键词优化平台
  • 网站肯定被k/seo是什么工作
  • 美丽乡村建设规划文本网站/国际军事新闻最新消息今天
  • 天津外贸网站建设公司/网络推广收费价目表
  • 网站做一年了没做301/广东互联网网络营销推广