什么是线程池
创建和销毁对象是非常耗费时间的
创建对象:需要分配内存等资源
销毁对象:虽然不需要程序员操心,但是垃圾回收器会在后台一直跟踪并销毁
对于经常创建和销毁、使用量特别大的资源,比如并发情况下的线程,对性能影响很大。
思路:
创建好多个线程,放入线程池中,使用时直接获取引用,不使用时放回池中。可以避免频繁创建销毁、实现重复利用
JDK1.5 起,提供了内置线程池
线程池的好处
1) 提高响应速度(减少了创建新线程的时间)
2) 降低资源消耗(重复利用线程池中线程,不需要每次都创建)
3) 提高线程的可管理性:避免线程无限制创建、从而销毁系统资源,降低系统稳定性,甚至内存溢出或者 CPU 耗尽
线程池的应用场合
1) 需要大量线程,并且完成任务的时间短
2) 对性能要求苛刻
3) 接受突发性的大量请求
使用线程池执行大量的 Runnable 命令
1 import java.util.concurrent.ExecutorService; 2 import java.util.concurrent.Executors; 3 4 public class Test1 { 5 public static void main(String[] args) { 6 //如何创建一个线程池 7 //(1)创建一个线程池,线程池中只有一个线程对象 8 // 执行时一个一个线程的执行,如果1个线程执行完成需要2秒,那20次需要40秒 9 //ExecutorService pool1=Executors.newSingleThreadExecutor(); 10 //(2)创建一个线程池,线程池中有线程的数量固定 11 // 固定为十个,执行时一次执行10个,只需2次共4秒 12 //ExecutorService pool1=Executors.newFixedThreadPool(10); 13 //(3)创建一个线程池,线程池中的线程的数量可以动态的改变 14 // 不做限制,一次执行完 只需1次共2秒 15 ExecutorService pool1=Executors.newCachedThreadPool(); 16 /**使用线程池执行大量的Runnable命令*/ 17 for(int i=0;i<20;i++){ 18 final int n=i; 19 //使用匿名内部类//任务 20 Runnable command=new Runnable() { 21 22 @Override 23 public void run() { 24 System.out.println("开始执行:"+n); 25 try { 26 Thread.sleep(2000);//休眠2秒 27 } catch (InterruptedException e) { 28 // TODO Auto-generated catch block 29 e.printStackTrace(); 30 } 31 System.out.println("执行结束:"+n); 32 } 33 };//任务结束 34 //将任务交给线程池中的线程去执行 35 pool1.execute(command); //execute实行 36 } 37 //关闭线程池 38 pool1.shutdown(); 39 } 40 }
--------------------------------------------------------
使用线程池执行大量的 Callable 任务
1 import java.util.ArrayList; 2 import java.util.List; 3 import java.util.concurrent.Callable; 4 import java.util.concurrent.ExecutionException; 5 import java.util.concurrent.ExecutorService; 6 import java.util.concurrent.Executors; 7 import java.util.concurrent.Future; 8 9 public class Test2 { 10 public static void main(String[] args) throws InterruptedException, ExecutionException { 11 12 // (1)创建一个线程池,线程池中只有一个线程对象 13 //ExecutorService pool1=Executors.newSingleThreadExecutor(); 14 // (2)创建一个线程池,线程池中有线程的数量固定 15 ExecutorService pool1=Executors.newFixedThreadPool(10); 16 // (3)创建一个线程池,线程池中的线程的数量可以动态的改变 17 //ExecutorService pool1 = Executors.newCachedThreadPool(); 18 //创建一个集合 19 List<Future> list=new ArrayList<Future>(); 20 /**使用线程池执行大量的Callable任务*/ 21 for(int i=0;i<20;i++){ 22 //使用匿名内部类 23 //创建任务 24 Callable<Integer> task=new Callable<Integer>() { 25 26 @Override 27 public Integer call() throws Exception { 28 Thread.sleep(2000); 29 return (int)(Math.random()*10)+1; //随机输出1到10 30 } 31 32 }; //任务结束 33 //将任务交能线程池 34 Future f=pool1.submit(task); 35 list.add(f); 36 //System.out.println(f.get()); 37 } 38 //遍历集合 39 for(Future ff:list){ 40 System.out.println(ff.get()); 41 } 42 //关闭线程池 43 pool1.shutdown(); 44 } 45 }