Java线程池总结

原创 2017年08月10日 09:49:20

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

    线程池就是一个线程的容器,每次只执行额定数量的线程, 线程池作用就是限制系统中执行线程的数量。采用线程池不仅调整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<Runnable> workQueue) 

 

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

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

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

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

workQueue 表示存放任务的队列。

 

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

 

线程池的工作过程如下:

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

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

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

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

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

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

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

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

   这样的过程说明,并不是先加入任务就一定会先执行。假设队列大小为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。

复制代码
下面是一个线程池使用的例子:

public class TestThreadPool {  

    public static void main(String[] args) {  

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

         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();  
        }  
    }  
}
复制代码


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

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


如果你在学习Java的过程中遇到什么问题或者想获取学习资源的话请点击【此处】,我们一起学Java!

版权声明:本文为博主原创文章,未经博主允许不得转载。

线程池 ExecutorService 详细介绍以及注意点区别

线程池 ExecutorService 相信java开发都用到,这里做个简单笔记一 Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存...
  • chenaini119
  • chenaini119
  • 2016年07月07日 10:37
  • 15811

java线程池---编写自己的线程池

java线程池---编写自己的线程池
  • canot
  • canot
  • 2016年03月16日 12:25
  • 6500

Java并发编程:线程池的使用(非常棒,通俗易懂)

Java并发编程:线程池的使用   在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题:   如果并发的线程数量很多,并且每个线程都是执行一个时间...
  • u011531613
  • u011531613
  • 2017年03月13日 16:56
  • 14765

Java四种线程池的使用

Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 new...
  • hupitao
  • hupitao
  • 2014年04月25日 09:28
  • 19002

Java并发:终止线程和关闭线程池

一、任务的取消1.1标志位class ThreadOne implements Runnable { public volatile boolean isComplete = false; ...
  • jiq408694711
  • jiq408694711
  • 2016年03月29日 00:09
  • 12706

Java线程池例子

在做很多高并发应用的时候,单线程的瓶颈已经满足不了我们的需求,此时使用多线程来提高处理速度已经是比较常规的方案了。在使用多线程的时候,我们可以使用线程池来管理我们的线程,至于使用线程池的优点就不用说了...
  • catoop
  • catoop
  • 2015年12月04日 23:16
  • 13315

Java 四种线程池的用法分析

介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用,本文是基础篇。转载请标注原地址:http://blog.csdn.net/u011974987/article/de...
  • u011974987
  • u011974987
  • 2016年03月31日 16:34
  • 7361

Java中的线程池——3种常用的ThreadPoolExecutor

在Executor框架下,利用Executors的静态方法可以创建三种类型的常用线程池。他们可分别对应不同的应用场景,下面来看看这三个线程池。 1 FixedThreadPool 这个线程...
  • u010723709
  • u010723709
  • 2015年12月24日 09:25
  • 2137

Java线程池的设计与实现

权声明:本文为博主原创文章,未经博主允许不得转载。 目录(?)[+] 1 设计思路 多线程技术主要是针对CPU解决高效执行任务的问题,使用多线程技术可以增加C...
  • zp17764507932
  • zp17764507932
  • 2017年01月17日 14:38
  • 1250

java中线程池的几种实现方式

1、线程池简介:     多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。         假设一个服务器完成一项任务所需时间为:T...
  • w2393040183
  • w2393040183
  • 2016年08月11日 00:23
  • 8634
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java线程池总结
举报原因:
原因补充:

(最多只允许输入30个字)