一.多线程
1.为什么使用线程池?
有时候系统需要处理非常多的执行时间很短的请求,如果每一个请求都需要创建一个新的线程的话,系统就会不断的进行线程的创建和销毁,有时花在创建和销毁上的时间,比线程真正执行的时间还长,而且当线程数量太多时,系统会受不了。
线程池主要解决以下问题:
(1)通过重用线程池中的线程,来减少每个线程创建和销毁的性能开销。
(2)多线程进行一些维护和管理,比如定时开始,周期执行,并发数控制等。
2.创建线程池的方式有哪些?
(1)newCachedThreadPool
创建一个可缓存线程池,如果线程长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
这种线程池的特点是:
1》工作线程的创建数量几乎没有限制,(其实也有限制的,数目为Interger. MAX_VALUE),这样可灵活的往线程池中添加线程。
2》如果长时间没有往线程池中提交任务,即工作线程空闲了指定时间(默认1分钟),则该线程自动终止,终止后,如果又提交了任务,则线程池重新创建一个工作线程。
(2)newFixedThreadPool
创建一个指定工作线程数的线程池,每提交一个任务就创建一个 工作线程,如果线程数量达到线程初始的最大值,则将提交的任务存到池队列中。
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
参数:nThreads是线程池中线程的数量
这种线程池即使在线程池空闲时(即线程池中没有可执行任务时),也不会释放工作线程,也会占用一定的系统资源。
(3)newSingleThreadExecutor
创建一个单线程化的Executor,即只创建唯一的工作线程来执行任务,它只会用唯一的工作线程来
执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。如果这个线程异常结束,会有
另一个取代它,保证顺序执行。单工作线程最大的特点是可保证顺序地执行各个任务,并且在任意给
定的时间不会有多个线程是活动的。
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
(4)newScheduleThreadPool
创建一个定长的线程池,而且支持定时以及周期性任务的执行。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); }