四,线程池
概念:线程池的本质是一个容器,在该容器中存放若干个线程对象,当有任务需要使用线程对象时,直接从池中获取线程对象而不去临时额外的创建,当任务执行完毕后,会将使用完的线程对象归还到池中,也便于下一次的使用。
线程池的好处:
- 提高了线程对象的复用性,每个线程对象在使用完毕后都会归还到池中
- 控制线程并发数量,降低服务器压力,统一管理所有线程;
- 提升系统响应速度,假如创建线程用的时间为T1,执行任务用的时间为T2,销毁线程用的时间为T3,那么使用线程池就免去了T1和T3的时间;
只要有并发的地方、任务数量大或小、每个任务执行时间长或短的都可以使用线程池;
只不过在使用线程池的时候,注意一下设置合理的线程池大小即可;
使用线程池要使用线程池的核心类
Executors
,它是线程池的工厂类,用于创建线程池
Executors
类中提供了生产线程池的静态方法newFixedThreadPool(int nThreads)
,用于创建一个固定数量线程对象的线程池,这个方法会返回一个用于获取线程对象并开启线程的对象ExecutorService
。
ExecutorService
中提供了submit(Runnable r)
,调用这个方法会自动从池中获取线程对象,并开启线程执行参数Runnable实现类中重写的run()。注:即使线程对象已经全部归还,线程池仍然处于开启状态,因为线程池在等待其他新的任务来获取池中的线程对象。可以通过调用
shutdown()
来手动关闭线程池,一旦线程池被关闭了,就不能再从池中获取线程对象,否则会发生RejectedExecutionException
拒绝执行异常。MyRunnable mr = new MyRunnable(); ExecutorService service = Executors.newFixedThreadPool(3); service.submit(mr); service.submit(mr); service.submit(mr); service.submit(mr); service.shutdown();