使用线程池的好处:
1.减少在创建和销毁线程上所花的时间以及系统资源的开销
2.如不使用线程池,有可能造成系统创建大量线程而导致消耗完系统内存以及”过度切换”。
3.如果在web应用中使用线程,如timer,但是需要设置守护线程,这样在tomcat关闭时,线程也随之关闭。但有些线程不会随着tomcat的关闭而关闭。如:thread 。所以一般需要用线程池统一管理
项目应用的例子
1.线程池执行timer定时任务
ScheduledExecutorService scheduled_pool = Executors.newScheduledThreadPool(1); Calendar currentDate = Calendar.getInstance(); System.out.println(currentDate.getTime()); long now = currentDate.getTime().getTime(); currentDate.add(Calendar.SECOND, 10); //Date date = calendar.getTime(); long delay = currentDate.getTime().getTime()-now ; long interval = 10*1000; System.out.println(delay); scheduled_pool.scheduleAtFixedRate(new TestTimerRunable(), delay, interval,TimeUnit.MILLISECONDS);
线程池执行thread线程
ScheduledExecutorService scheduled_pool = Executors.newScheduledThreadPool(1); Thread thread = new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub } }); thread.setDaemon(true);//线程设置为守护线程 则容器关闭后,这些守护线程会立即关闭 scheduled_pool.execute(thread);
2.web应用
1)web.xml中配置监听器,在系统启动时加载线程池
<listener-class> com.xxx.common.listener.ThreadPoolListener </listener-class>
2)监听器配置
public class ThreadPoolListener implements ServletContextListener{ public static ScheduledExecutorService scheduled_pool = Executors.newScheduledThreadPool(10); private Logger log = LoggerFactory.getLogger(this.getClass()); @Override public void contextDestroyed(ServletContextEvent arg0) { scheduled_pool.shutdown();//关闭线程池 if (!scheduled_pool.isShutdown()) { try { Thread.currentThread().wait(5000); if (!scheduled_pool.isShutdown()) { scheduled_pool.shutdownNow();//关闭线程池 (强行关闭) } } catch (InterruptedException e) { log.error("关闭所有线程错误",e.getMessage()); } finally{ if (!scheduled_pool.isShutdown()) { scheduled_pool.shutdownNow(); } } } log.info("所有线程关闭"+scheduled_pool.isShutdown()); } @Override public void contextInitialized(ServletContextEvent arg0) { } }