Java并发编程之线程池的使用

1. 为什么要使用线程

随着科技的进步,现在的电脑及服务器的处理器数量都比较多,以后可能会越来越多,比如我的工作电脑的处理器有8个,怎么查看呢?

计算机右键--属性--设备管理器,打开属性窗口,然后点击“设备管理器”,在“处理器”下可看到所有的处理器:

Java并发编程之线程池的使用

Java并发编程之线程池的使用

也可以通过以下Java代码获取到处理器的个数:

System.out.println("CPU个数:" + Runtime.getRuntime().availableProcessors());

运行结果如下所示:

CPU个数:8

既然处理器的个数增加了,如果还使用传统的串行编程,就有点浪费资源了,因此,为了提高资源利用率,让各个处理器都忙碌起来,就需要引入并发编程,要引入并发编程,就引入了多线程

可以说,使用多线程的最直接目的就是为了提高资源利用率,资源的利用率提高了,系统的吞吐率也就相应提高了。

2. 为什么要使用线程池?

在一定的范围内,增加线程可以提高应用程序的吞吐率,但线程并不是越多越好(因为线程的创建与销毁都需要很大的开销),如果超过了某个范围,不仅会降低应用程序的执行速度,严重的话,应用程序甚至会崩溃,以至于不得不重启应用程序。

为了避免这种问题,就需要对应用程序可以创建的线程数量进行限制,确保在线程数量达到限制时,程序也不会耗尽资源,线程池就是为了解决这种问题而出现的。

线程池:管理一组工作线程的资源池。

线程池与工作队列密切相关,工作队列中保存了所有等待执行的任务。

工作者线程的任务就是从工作队列中获取一个任务,执行任务,然后返回线程池并等待下一个任务。

使用线程池可以带来以下好处:

通过重用现有的线程而不是创建新线程,可以在处理多个任务时减少在线程创建与销毁过程中产生的巨大开销。

当任务到达时,工作线程通常已经存在,因此不会由于等待创建线程而延迟任务的执行,从而提高了响应性。

可以通过调整线程池的大小,创建足够多的线程使处理器保持忙碌状态,同时还可以防止过多线程相互竞争资源而使应用程序耗尽内存或崩溃。

3. 创建线程池 3.1 使用Executors静态方法创建(不推荐)

Executors类提供了以下4个静态方法来快速的创建线程池:

newFixedThreadPool

newCachedThreadPool

newSingleThreadExecutor

newScheduledThreadPool

首先看下newFixedThreadPool()方法的使用方式:

ExecutorService threadPool = Executors.newFixedThreadPool(10);

它的源码为:

public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }

说明:newFixedThreadPool将创建一个固定长度的线程池,每当提交一个任务时就创建一个线程,直到达到线程池的最大数量,这时线程池的规模将不再变化(如果某个线程由于发生了未预期的Exception而结束,那么线程池会补充一个新的线程)。

然后看下newCachedThreadPool()方法的使用方式:

ExecutorService threadPool = Executors.newCachedThreadPool();

它的源码为:

public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }

说明:newCachedThreadPool将创建一个可缓存的线程池,如果线程池的规模超过了处理需求时,那么将回收空闲的线程,而当需求增加时,则添加新的线程,线程池的最大规模为Integer.MAX_VALUE。

然后看下newSingleThreadExecutor()方法的使用方式:

ExecutorService threadPool = Executors.newSingleThreadExecutor();

它的源码为:

public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }

说明:newSingleThreadExecutor是一个单线程的Executor,它创建单个工作者线程来执行任务,如果这个线程异常结束,就创建一个新的线程来替代。

newSingleThreadExecutor可以确保依照任务在队列中的顺序来串行执行。

最后看下newScheduledThreadPool()方法的使用方式:

ExecutorService threadPool = Executors.newScheduledThreadPool(10);

它的源码为:

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); } public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue()); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjwfw.html