多线程(五)

1、案例----线程池

         因为进程创建销毁时比较低效(内存的申请和释放),所以引入了线程。线程共享内存资源,新的线程可以利用之前的资源而不需要重新申请,此时效率会提高。

        但若创建线程的速率进一步变频繁了,此时线程的创建和销毁仍不可忽视。想要进一步优化速度,采用线程池。

提问:为什么在线程池中取比创建线程快?

答:创建线程实在操作系统的内核中完成的,涉及到用户态到内核态的切换操作,这个操作存在一定开销。

从线程池取线程,把线程放回线程池,这是纯用户态的实现的逻辑。从系统这里创建进程,则是用户态到内核态共同完成的逻辑。

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

(1)线程池的使用 

 

 (2)自己实现线程池

 =》一个线程池可以同时提交N个任务。

=》对应的线程池中有M个线程来负责完成这N个任务。

思路:生产者消费者模型,可以解决将N个任务分给M个线程的问题。先应用一个阻塞队列,每个被提交的任务,都放在阻塞队列中。用M个线程来取队列元素,如果队列空了,M个线程阻塞等待;如果队列不为空,每个线程都取任务并执行,再来取下一个任务......知道队列为空。

以下是一个固定线程池数目的线程池的实现:

 执行结果:

 线程池的优点:

=》 降低资源消耗。减少线程的创建和销毁带来的性能开销。

=》提高响应速度。当有任务来时,可以直接使用,不用等待创建线程。

=》可管理性。进行统一的分配,监控,避免大量线程因互相抢占系统资源导致阻塞现象。

(3)JAVA线程池有几个核心的参数,这几个参数的作用是: 

->corePoolSize:核心线程数。当提交一个新的任务到线程池,如果当前线程池运行的线程数(包括闲置的线程)小于核心线程数,则会创建一个新的线程作为核心线程来执行该任务。

->maximumPoolSize:线程池允许的最大线程数。当提交一个新的任务到线程池,如果当前线程池运行的线程数(包括闲置的线程)大于核心线程数,但小于允许的最大线程数,并且等待队列满时,会创建一个新的线程处理该任务。

->keepAliveTime:当线程池中线程数量大于核心线程数时,限制的线程最长存活的时间

->unit:时间单位

->workQueue:保存任务的队列,当线程数大于核心线程数时,新的任务将保存到该队列。

->threadFactory:线程工厂,线程池中的线程都是通过该工厂创建的。

->handler: 任务拒绝执行策略。拒绝策略如下:

        =》AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。

        =》DiscardPolicy:丢弃新来的任务

        =》DiscardOldestPolicy:丢弃最先来的任务,然后重新尝试执行任务

        =》CallerRunsPolicy:把该任务交给添加此任务的线程来执行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值