java号码池_Java线程池总结

假定1个服务器完成1项任务所需时间为:T1 创建线程时间,T2 在线程中履行任务的时间,T3 烧毁线程时间。当T1 + T3 远大于 T2时,采取多线程技术可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。

线程池就是1个线程的容器,每次只履行额定数量的线程, 线程池作用就是限制系统中履行线程的数量。采取线程池不但调剂T1,T3产生的时间段,而且它还显著减少了创建线程的数目。

为何要用线程池:

1)减少了创建和烧毁线程的次数,每一个工作线程都可以被重复利用,可履行多个任务

2)可以根据系统的承受能力,调剂线程池中工作线线程的数目,避免由于由于消耗过量的内存,而把服务器累趴下(每一个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)

Java1.5以后,Java 提供了自己的线程池ThreadPoolExecutor类。

ThreadPoolExecutor使用简介

线程池类为java.util.concurrent.ThreadPoolExecutor,经常使用构造方法为:

public ThreadPoolExecutor(

int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue workQueue)

corePoolSize 指的是保存的线程池大小。

maximumPoolSize 指的是线程池的最大大小。

keepAliveTime 指的是空闲线程结束的超时时间。

unit 是1个枚举,表示 keepAliveTime 的单位。

workQueue 表示寄存任务的队列。

1个任务通过 execute(Runnable)方法被添加到线程池,任务就是1个 Runnable类型的对象,任务的履行方法就是 Runnable类型对象的run()方法。

线程池的工作进程以下:

1、线程池刚创建时,里面没有1个线程。任务队列是作为参数传进来的。不过,就算队列里面有任务,线程池也不会马上履行它们。

2、当调用 execute() 方法添加1个任务时,线程池会做以下判断:

a. 如果正在运行的线程数量小于 corePoolSize,那末马上创建线程运行这个任务;

b. 如果正在运行的线程数量大于或等于corePoolSize,那末将这个任务放入队列。

c. 如果这时候候队列满了,而且正在运行的线程数量小于 maximumPoolSize,那末还是要创建线程运行这个任务;

d. 如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那末线程池会抛出异常,告知调用者“我不能再接受任务了”。

3、当1个线程完成任务时,它会从队列中取下1个任务来履行。

4、当1个线程无事可做,超过1定的时间(keepAliveTime)时,线程池会判断,如果当前运行的线程数大于 corePoolSize,那末这个线程就被停掉。所以线程池的所有任务完成后,它终究会收缩到 corePoolSize 的大小。

这样的进程说明,其实不是先加入任务就1定会先履行。假定队列大小为10,corePoolSize为3,maximumPoolSize 为6,那末当加入 20 个任务时,履行的顺序就是这样的:首先履行任务 1、2、3,然后任务4~13被放入队列。这时候候队列满了,任务 14、15、16 会被马上履行,而任务 17~20 则会抛出异常。终究顺序是:1、2、3、14、15、16、4、5、6、7、8、9、10、11、12、13。

f468c4869860cfe6737263cddb4bdc95.gif

下面是1个线程池使用的例子:

public class TestThreadPool {

public static void main(String[] args) {

ThreadPoolExecutor threadPool = new ThreadPoolExecutor(3, 6, 5,TimeUnit.SECONDS, new LinkedBlockingQueue());

for (int i = 1; i <= 20; i++) {

threadPool.execute(new ThreadPoolTask());

//threadPool.shutdown(); }

}

}

创建 ThreadPoolTask类:

public class ThreadPoolTask implements Runnable {

public void run() {

try {

System.out.println("开始履行任务:" + attachData);

Thread.sleep(100);

}

catch(Exception e){

e.printStackTrace();

}

}

}

f468c4869860cfe6737263cddb4bdc95.gif

1、BlockingQueue 只是1个接口,经常使用的实现类有 LinkedBlockingQueue 和 ArrayBlockingQueue。用 LinkedBlockingQueue 的好处在于没有大小限制。这样的话,由于队列不会满,所以 execute() 不会抛出异常,而线程池中运行的线程数也永久不会超过 corePoolSize 个,keepAliveTime 参数也就没成心义了。

2、shutdown() 方法不会阻塞。调用 shutdown() 方法以后,主线程就马上结束了,而线程池会继续运行直到所有任务履行完才会停止。如果不调用 shutdown() 方法,那末线程池会1直保持下去,以便随时添加新的任务。

学习Java的同学注意了!!!

学习进程中遇到甚么问题或想获得学习资源的话,欢迎加入Java学习交换群,群号码:183993990我们1起学Java!

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值