美文网首页
Java线程池

Java线程池

作者: 黎繁介 | 来源:发表于2018-06-10 16:20 被阅读14次

        由于系统频繁创建线程和销毁线程成本是比较高的,尤其是需要大量短时间的线程,于是有了线程池,可以很好的提高系统性能。线程池在系统启动时,便创建大量的空闲线程,当将一个Runnable对象传给线程池时,线程池的其中一个线程便执行Runnable对象的run()方法,执行完后,线程并非销毁而是回到线程池进入空间状态,等待下一个任务的到来。线程池可以有效的控制并发线程的数量,不让它超过系统值,而引起的JVM崩溃。        


ThreadPoolExecutor是线程池里最核心的一个类,我们来通过它了解线程池:

ThreadPoolExecutor构造器

可以看出ThreadPoolExecutor类给了4个构造器供我们使用,下面我们来详解构造器的7个参数:

        corePoolSize———该池中的最大核心线程数量,核心线程默认保存在池中,即使是空闲状态的,除非设置了allowCoreThreadTimeOut为true(设置这个后,核心线程闲置一定时间(由下面的参数决定时间)后,就会被销毁掉)。

        maximumPoolSize———允许线程池的最大线程数量(最大线程数量=核心线程数量+非核心线程数量)。

        keepAliveTime———空闲状态下的非核心线程被销毁前等待的时间(核心线程设置了                    allowCoreThreadTimeOut的话同样)。

        unit———keepAliveTime的单位,枚举类型,有7个静态属性:

                TimeUnit.DAYS;              //天

                TimeUnit.HOURS;            //小时

                TimeUnit.MINUTES;          //分钟

                TimeUnit.SECONDS;          //秒

                TimeUnit.MILLISECONDS;      //毫秒

                TimeUnit.MICROSECONDS;      //微妙

                TimeUnit.NANOSECONDS;      //纳秒

        workQueue———用于在执行任务之前使用的队列(就是添加线程任务后,任务进入队列后,不同的队列执行不同的策略),常用的类型有如下几种:

        SynchronousQueue:队列接收到任务,直接提交给线程池处理,不保留它,如果所有线程都在工作了,则新建一个线程来处理这个任务。(线程数超过maximumPoolSize会不能新建线程而报错,一般把maximumPoolSize设置为Integer.MAX_VAULE)

        LinkedBlockingQueue:队列接收到任务,如果当前线程数不超过corePoolSize,既新建核心线程执行这个任务,否则任务入队列等待。

        ArrayBlockingQueue:指定队列的长度,如果当前线程未超过corePoolSize,新建核心线程处理任务,若超过了,则入队列等待,又如果队列已满,则新建非核心线程执行任务,再则总线程数超过了最大线程数,则发生错误。

        DelayQueue:队列内元素必须实现Delayed接口(传入的任务必须先实现Delayed接口),先入队,到指定时间后才执行。

        threadFactory———线程工厂,创建线程的方式。

        handler———抛出异常专用,针对上面出现的异常的处理方式。


ThreadPoolExecutor类的几个常用方法:

        execute(Runnable command):提交接受到的任务。

        shutdown():队列不在接受新的任务,线程池内的任务执行完后,关闭线程池。

        shutdownNow():队列不接受新的任务,并且队列内任务移除,并尝试停止正在执行的任务,关闭线程池。


        ThreadPoolExecutor类让我们能自主定义出需要的各种线程池,但是每次使用线程池的时候,不想搞这么多参数怎么办?于是Java提供了4中常见的线程池供我们直接使用(通过Executors类创建):

CachedThreadPool(可缓存线程池)

ExecutorService cachedThreadPool=Executor.newCachedThreadPool();

源码:

规则:1.线程数量无限制

            2.有空闲线程用空闲线程,无空闲线程则新建线程。

FixedThreadPool(定长线程池)

ExecutorService fixedThreadPool=Executors.newFixedThreadPool(int nThread);

源码:

规则:1.控制线程最大并发数(即同时执行的线程)

            2.超出的线程在队列中等待。

SingleThreadExecutor(单线程化的线程池)

ExecutorService singleThreadExecutor=Executors.newSingleThreadExecutor();

源码:

规则:1.有且只有一个线程执行。

            2.任务根据入队列规则执行,即先入队列先执行。

ScheduledThreadPool(调度型线程池)

ExecutorService scheduledThreadPool=Executors.newScheduledThreadPool(int corePoolSize);

源码:

规则:1.一定时间后执行或周期性执行。


不难发先,这些常用的线程池其实就是变相调用ThreadPoolExecutor类, 所以说要是没有我们想要的,还是老老实实的写吧。

线程池添加任务有submit和execute,它们的区别:

        1.接受的参数不一样

        2.submit有返回值

        3.execute是Executor接口中唯一定义的方法,submit是ExecutorService接口定义的方法(该接口继承Executor接口)


-------------上一节“Java-Callable和Future”---------------

-------------下一节“Java-线程相关类”--------------------

相关文章

网友评论

      本文标题:Java线程池

      本文链接:https://www.haomeiwen.com/subject/ghbfeftx.html