在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁。如何利用已有对象来服务就是一个需要解决的关键问题,其实这就是一些”池化资源”技术产生的原因。
合理利用线程池能够带来三个好处。第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。但是要做到合理的利用线程池,必须对其原理了如指掌。
java.util.concurrent.Executor接口执行已提交的Runnable任务的对象。此接口提供一种将任务提交与每个任务将如何运行的机制(包括线程使用的细节、调度等)分离开来的方法。通常使用 Executor 而不是显式地创建线程。
Java通过Executors提供四种线程池,分别为:
1、newFixedThreadPool(int nThreads)
创建一个可重用固定线程集合的线程池,以共享的无界队列方式来运行这些线程。
package com.xieyincai.thread; import java.util.concurrent.Executor; import java.util.concurrent.Executors; public class ThreadPoolDemo { private static final int THREADNUMBER = 3; private static final Executor exec = Executors.newFixedThreadPool(THREADNUMBER); public static void main(String[] args) { // TODO Auto-generated method stub for(int i=0; i<10; i++) { Runnable task = new Runnable() { public void run() { System.out.println(Thread.currentThread().getName()); } }; exec.execute(task); } } }
输出如下:
pool-1-thread-1 pool-1-thread-2 pool-1-thread-3 pool-1-thread-2 pool-1-thread-1 pool-1-thread-1 pool-1-thread-1 pool-1-thread-2 pool-1-thread-3 pool-1-thread-1
2、newCachedThreadPool()
创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。
package com.xieyincai.thread; import java.util.concurrent.Executor; import java.util.concurrent.Executors; public class ThreadPoolDemo { private static final Executor exec = Executors.newCachedThreadPool(); public static void main(String[] args) { // TODO Auto-generated method stub for(int i=0; i<20; i++) { Runnable task = new Runnable() { public void run() { System.out.println(Thread.currentThread().getName()); } }; exec.execute(task); } } }
输出如下:
pool-1-thread-1 pool-1-thread-4 pool-1-thread-3 pool-1-thread-2 pool-1-thread-5 pool-1-thread-8 pool-1-thread-6 pool-1-thread-9 pool-1-thread-6 pool-1-thread-8 pool-1-thread-4 pool-1-thread-5 pool-1-thread-2 pool-1-thread-3 pool-1-thread-1 pool-1-thread-7 pool-1-thread-13 pool-1-thread-12 pool-1-thread-11 pool-1-thread-10
3、newSingleThreadExecutor()
创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。
package com.xieyincai.thread; import java.util.concurrent.Executor; import java.util.concurrent.Executors; public class ThreadPoolDemo { private static final Executor exec = Executors.newSingleThreadExecutor(); public static void main(String[] args) { // TODO Auto-generated method stub for(int i=0; i<10; i++) { Runnable task = new Runnable() { public void run() { System.out.println(Thread.currentThread().getName()); } }; exec.execute(task); } } }
输出如下:
pool-1-thread-1 pool-1-thread-1 pool-1-thread-1 pool-1-thread-1 pool-1-thread-1 pool-1-thread-1 pool-1-thread-1 pool-1-thread-1 pool-1-thread-1 pool-1-thread-1
4、newScheduledThreadPool(int corePoolSize)
创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。
package com.xieyincai.thread; import java.util.concurrent.Executor; import java.util.concurrent.Executors; public class ThreadPoolDemo { private static final int THREADNUMBER = 3; private static final Executor exec = Executors.newScheduledThreadPool(THREADNUMBER); public static void main(String[] args) { // TODO Auto-generated method stub for(int i=0; i<10; i++) { Runnable task = new Runnable() { public void run() { System.out.println(Thread.currentThread().getName()); } }; exec.execute(task); } } }
输出如下:
pool-1-thread-1 pool-1-thread-3 pool-1-thread-2 pool-1-thread-3 pool-1-thread-1 pool-1-thread-3 pool-1-thread-2 pool-1-thread-3 pool-1-thread-1 pool-1-thread-2