线程和线程池

一、无限制创建线程的不足:
1.线程生命周期的开销非常高:
1)线程的创建过程需要时间,延迟处理请求,并且需要JVM和操作系统提供一些辅助操作;
2)如果请求的到达率非常高,并且请求的处理是轻量级的,那么为每一个请求创建线程将消耗大量资源

2.资源消耗:
活跃的线程会消耗系统资源,尤其是内存
1)如果可运行的线程数量超过可用的处理器的数量,那么有些线程将闲置;
2)大量空闲的线程会占用内存,给垃圾回收带来压力,而且大量线程在竞争CPU资源时还将产生其他资源的消耗;
3)如果已经有了足够多线程使所有CPU保持忙碌状态,那么再创建更多线程反而会降低性能

3.稳定性:
在可创建线程的数量上存在一个限制,包括JVM启动参数、Thread构造函数中请求的栈大小、以及底层系统对线程的限制等。
如果破坏了这些限制,很可能抛出OutOfMemoryError异常

在一定范围内增加线程可以提高系统的吞吐率,但如果超出了这个范围,再创建更多的线程只会降低程序的执行速度,并且如果过多创建一个线程,那么整个应用程序将崩溃。因此需要对应用程序可以创建的线程数量进行限制。

二、Executor
public interface Executor
void execute (Runnable command) ;
}
将任务的提交过程与执行过程解耦,并且只需要采用另外一种不同的Exceutor实现,就可以改变服务器的行为。
线程池的优势:通过重用现有线程而不是创建多个新线程,可以在处理多个请求时分摊在线程创建和销毁过程中产生的巨大开销。
Executors中的静态工厂方法创建线程池:
     Executors.newCacheThreadPool();
        创建一个可根据需要创建新线程的线程池(可缓存的线程池)。如果线程池的当前规模超过了处理需求,将回收空闲线程;当需求增加时,则可添加新的线程,线程池的规模不存在任何限制。
     Executors.newFixedThreadPool(int nThreads);
        创建一个可重用固定线程集合的线程池,以共享的无界队列方式运行这些线程。先进先出。
每当提交一个任务时就创建一个线程,直到达到线程池的最大数量,如果由于某个线程池发生Exception而结束,线程池会补充一个新的线程。
     Executors.newScheduledThreadPool(int corePoolSize);
        创建一个固定长度的线程池,它可安排在给定延迟后运行命令或者定期执行,类似Timer
     Executors.newSingleThreadExecutor();
        创建一个使用单个worker(工作者)线程来执行任务的Executor,以无界队列的方式来运行该线程。如果线程异常结束,会创建另一个线程来替代。能保证依照任务队列总的顺序来串行执行。

三、ExecutorService
Executor的实现通常会创建线程执行任务,但JVM只有在所有(非守护)线程全部终止后才会退出,因此无法正确关闭Executor,JVM将无法结束。
为解决执行服务的生命周期问题,Executor扩展了ExecutorService接口,添加了一些用于生命周期管理的方法。
public interface ExecutorService extends Executor {
void shutdown () ;
List<Runnable> shutdownNow () ;
boolean isShutdown () ;
boolean isTerminated () ;
boolean awaitTermination ( long timeout , TimeUnit unit) throws InterruptedException ;
< T > Future< T > submit (Callable< T > task) ;
< T > Future< T > submit (Runnable task , T result) ;
Future<?> submit (Runnable task) ;
< T > List<Future< T >> invokeAll (Collection<? extends Callable< T >> tasks) throws InterruptedException ;
< T > List<Future< T >> invokeAll (Collection<? extends Callable< T >> tasks ,long timeout , TimeUnit unit)
throws InterruptedException ;
< T > T invokeAny (Collection<? extends Callable< T >> tasks)
throws InterruptedException , ExecutionException ;
< T > T invokeAny (Collection<? extends Callable< T >> tasks ,long timeout , TimeUnit unit)
throws InterruptedException , ExecutionException , TimeoutException ;
}
ExecutorService的生命周期有三种状态:运行、关闭、已终止
1)ExecutorService在初始创建时处于运行状态;
2)shutdown()方法将平缓的关闭线程,不再接受新的任务,同时等待已提交的任务执行完成(包括还未开始执行的任务),shutdownNow()方法将执行粗暴的关闭过程,将尝试取消所有运行中的任务。
3)等所有任务都完成后,ExecutorService将转入终止状态,可以调用awaitTermination()方法来等待ExecutorService到达终止状态,调用之后会立即shutdown,从而产生同步关闭ExecutorService的效果,或调用isTermination()方法来轮询ExecutorService是否已经终止。

猜你喜欢

转载自blog.csdn.net/csdfh/article/details/80859119