系统启动一个新线程成本比较高,当程序中需要创建大量生存期很短暂的线程时,使用线程池可以很好的提高性能。
与数据库连接池类似的是,线程池在系统启动时及创建大量空闲的线程。程序将一个Runnable对象传递给线程池,线程就会启动一条线程来执行该对象的run方法。当run方法执行结束后,该线程并不会死亡,而是返回线程池成为空闲状态,等待执行下一个Runnable对象的run方法。
创建线程池Java提供了一个Executors工厂类来产生线程池,该工厂类包含以下几个静态工厂方法来创建线程池:
newCachedThreadPool():创建一个具有缓存功能的线程池,系统根据需要创建线程,这些线程将被缓存在线程池中;
newFixedThreadPool(int nThreads):创建一个可重用的,具有固定线程数的线程池;
newSingleThreadExecutor():创建一个只有单线程的线程池,相当于newFixedThreadPool参数传入1;
newScheduledThreadPool(int corePoolSize):创建具有指定线程数的线程池,它可以在指定延迟后执行线程任务。corePoolSize指池中保存的线程数;
newSingleThreadScheduledExecutor():创建只有一条线程的线程池,可以在指定延迟后执行任务。
上面5个方法中的前三个方法返回一个ExecutorService对象,该对象代表一个线程池,它可以执行Runnable对象和Callable对象所代表的线程。后两个方法返回一个ScheduledExecutorService对象,它是ExecutorService的子类,可以在指定延迟后执行线程任务。
执行线程任务ExecutorService类提供了submit方法来执行线程任务并返回执行结果(如果有的话);ScheduledExecutorService则额外提供了schedule、scheduleAtFixedRate和scheduleAtFixedDelay方法来延迟执行线程任务。
关闭线程池当用完一个线程池后,应该调用线程池的shutdown()方法,该方法将启动线程池的关闭序列,调用了shutdown()方法的线程池将不再接受新任务,但会将以前接收的任务处理完成。当线程池中的所有任务都执行完成后,池中的所有线程都会死亡。另外也可调用线程池的shutDownNow()方法关闭线程池,该方法会试图停止所有正在执行的任务,暂停处理正在等待的任务,并返回等待的任务列表。
总结使用线程池执行线程任务的步骤如下:
调用Executor类的静态工厂方法创建一个ExecutorService对象,该对象代表一个线程池;
创建Runnable或Callable接口实现类的实例,作为线程执行任务;
调用ExcutorService的submit方法来提交Runnable或Callable实例;
当不想提交任何任务时调用ExcutorService的shutdown方法来关闭线程池。
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadPool { public static void main(String[] args){ ExecutorService pool = Executors.newFixedThreadPool(3); pool.submit(new MyThread() ); pool.submit(new MyThread() ); pool.submit(new MyThread() ); pool.shutdown(); } } class MyThread implements Runnable{ static int count = 0; public void run(){ for(int i=0; i<10; i++){ System.out.println(Thread.currentThread().getName() + "-------" + i + "------" + count++); } } }