网络层架构设计与实战三之线程池原理及线程的终止

1、


2、

ThreadPoolExecutor参数:

corePoolSize:核心线程数

maximumPoolSize:最大线程数

keepAliveTime:存活的时间

TimeUnit:时间单位

BlockingQueue<Runnable>workQueue :队列

ThreadFactory:线程工厂


②new SynchronousQueue():

放入队列的时候一直处于阻塞状态,数据必需得等上一个数据



new LinkedBlockingDeque():可以指定一个size,如果不指定的话是没有限制的,可以插入任何数据


③new  ThreadFactory():

指定线程的名字


3、new ThreadPoolExecutor(2,4,60,TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10))


创建了一个线程池,核心线程池核心线程数为2,最大线程数为4,队列长度是10


当线程池刚启动的时候,会去创建同等长度的核心线程。当这个时候向线程池中提交任务,会判断核心线程是否启动,如果没有启动,会启动两个核心线程。接下来再向线程池中提交任务的时候,会向队列中提交数据,后续任务会提交到ArrayBlockingQueue当中。但是,如果提交的任务比较多,比如说已经提交了10个任务,这时候会判断最大线程数,如果最大线程数还有富余的话,他就会增加 2  个线程( 最大线程数 - 核心线程数  )。如果最大线程数已经创建满了,这时候还向里面提交任务,就会抛出异常了,默认情况下会直接拒绝任务的提交

①当创建两个任务的时候,队列中是没有任何数据的,长度是0,说明任务都是放在了核心线程去做了



②创建5个任务

这时发现核心线程已经满了,就把任务提交到了队列当中,队列当中有3个这样的数据(任务数-核心线程数)



③创建14个任务

该任务为边界值,最大线程数+队列长度数=14,这时候也是没有任务问题的



④当创建的任务数过多,最大线程数为4,队列长度已经为10,此时还向队列中添加任务,就会报异常




默认情况下是抛出下面的异常,但是也可以指定




也可以通过在构造方法中指定对应的策略来进行不同的处理




它有不同的子类,实现了不同的策略




但是如果将ArrayBlockingQueue换成了LinkedBlockingDeque,这是一个队列没有限制的,也就是说当创建完两个核心线程后,一直向LinkedBlockingDeque中添加数据,如果LinkedBlockingDeque中的数据非常多,会出现一个非常延时的等待,因为它需要把任务一个个去执行,而且最大的核心线程是不会被开启的,因为LinkedBlockingDeque最大线程永远不满足,所以永远不会开启最大线程,那么对于当前应用程序,最大线程就是核心线程数2,所有任务都堆积到LinkedBlockingDeque中。这种情况下不建议使用LinkedBlockingDeque,因为它会导致应用程序的资源不断进行消耗,最好是给每一个任务指定一个长度,这时候对资源的消耗都是可控的

4、为什么要有队列?

队列就是按照先进先出的顺序进行排列。原因是在进行网络请求的时候,在一瞬间可能有大量的请求,但是电脑的cpu资源是有限的,它不可能同时处理很多的请求,如果此时处理不了,就需要队列了。我们把功能处理的请求都放在队列当中进行排队,当线程或资源充足的时候,从队列中取出对应的任务去执行相应的结果

5、

有限队列:队列长度是有限制的

SynchronousQueue:队列长度就一个,放进去一个数据之后必须取出来,然后才能继续存放数据,否则如果再次存放的话,它会处于阻塞状态

ArrayBlockingQueue:它是基于数组的一个blockingqueue

无限队列:队列长度是没有限制的


6、如何终止线程?

①通过一个变量终止线程,但是在多线程中可能会存在变量已经被修改了,但是还是处于原来状态的线程,这个是使用变量终止线程遇到的问题

②对变量使用volitile关键字,也就是对变量进行修改之后,其它变量也会同步它所修改的信息,本质上是可以解决这样的问题



③通过flag进行修改






运行后发现这种方式是可以对线程进行终止的




④线程处于休眠状态,或正在处理耗时操作,此时直接通过flag进行终止是不能成功的

让当前线程休眠100毫秒




原来的线程休眠2s钟,发现不能立刻马上地终止原来的线程,一直处于运行状态,原来的线程运行结束后才进行了终止




⑤通过interrupt进行终止




运行后发现,只是发生了异常,但是并没有终止线程。也就是说,当调用interrupte方法后,会抛出异常,告诉线程已经中断了,实际上会走到catch语句当中,但实际上在catch语句中没有进行任何操作,下次while循环的时候,整个线程又变成一个正常的了,又可以继续运行。interrupt方法只是把线程的状态变成了一个中断的状态,必需在异常中进行相应的处理或者执行return语句,才可以真正地结束线程



在异常中执行return可以终止线程


使用volitile关键字使所有线程读取的都是同一个被改变之后的值,该值改变后线程可以立即执行,可以立即中断,用来控制while循环

Thread.interrupted()可以用来控制线程的执行

这是经常使用的终止线程的方法





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值