线程池的基本思想是一种对象池,在程序启动时就开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。
一个线程池包括以下四个基本组成部分:
讲到线程池,要重点介绍java.uitl.concurrent.ThreadPoolExecutor类,ThreadPoolExecutor线程池中最核心的一个类,ThreadPoolExecutor在JDK中线程池常用类UML类关系图如下:
我们可以通过ThreadPoolExecutor来创建一个线程池
new ThreadPoolExecutor(corePoolSize, maximumPoolSize,keepAliveTime, milliseconds,runnableTaskQueue, threadFactory,handler);
我们可以通过execute()或submit()两个方法向线程池提交任务,不过它们有所不同
threadsPool.execute(new Runnable() { @Override public void run() { // TODO Auto-generated method stub } });
try { Object s = future.get(); } catch (InterruptedException e) { // 处理中断异常 } catch (ExecutionException e) { // 处理无法执行任务异常 } finally { // 关闭线程池 executor.shutdown(); }
我们可以通过shutdown()或shutdownNow()方法来关闭线程池,不过它们也有所不同
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程
public class ThreadPoolExecutorTest1 { public static void main(String[] args) { ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); for (int i = 0; i < 1000; i++) { final int index = i; try { Thread.sleep(index * 1000); } catch (Exception e) { e.printStackTrace(); } cachedThreadPool.execute(new Runnable() { public void run() { System.out.println(Thread.currentThread().getName()+":"+index); } }); } } }
newFixedThreadPool创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待,指定线程池中的线程数量和最大线程数量一样,也就线程数量固定不变
示例代码如下
public class ThreadPoolExecutorTest { public static void main(String[] args) { ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);// 每隔两秒打印3个数 for (int i = 0; i < 10; i++) { final int index = i; fixedThreadPool.execute(new Runnable() { public void run() { try { System.out.println(Thread.currentThread().getName()+":"+index); //三个线程并发 Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }); } } }
newscheduledThreadPool创建一个定长线程池,支持定时及周期性任务执行。延迟执行示例代码如下.表示延迟1秒后每3秒执行一次
public class ThreadPoolExecutorTest3 { public static void main(String[] args) { ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5); scheduledThreadPool.scheduleAtFixedRate(new Runnable() { public void run() { System.out.println(Thread.currentThread().getName() + ": delay 1 seconds, and excute every 3 seconds"); } }, 1, 3, TimeUnit.SECONDS);// 表示延迟1秒后每3秒执行一次 } }
newSingleThreadExecutor创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行
public class ThreadPoolExecutorTest4 { public static void main(String[] args) { ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); for (int i = 0; i < 10; i++) { final int index = i; singleThreadExecutor.execute(new Runnable() { public void run() { try { System.out.println(Thread.currentThread().getName() + ":" + index); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); } } }
结果依次输出,相当于顺序执行各个任务。使用JDK自带的监控工具来监控我们创建的线程数量,运行一个不终止的线程,创建指定量的线程,来观察