Java高效并发(六)----jdk并发包的线程池认识

线程池

为了避免频繁的创建线程和销毁线程带来的消耗,我么创建线程池,让线程进行复用,在线程池中总有几个活跃的线程在工作,当有新任务提交时,空闲线程就可以去执行,而不必新建线程,当任务执行完毕不是销毁线程,而是把他归还给线程池,以便复用。


Executor框架

在J.U.C并发包中JDK提供了几个支持线程池的核心类,如下:

(1)java.util.concurrent.Executors

这个类扮演着线程池工厂的校色,有几个静态方法,用来创建线程池

public static ExecutorService newFixedThreadPool(int nThread):  创建指定线程数的线程池,该线程池中的线程数量不会改变,当有任务,有空闲线程则执行,没有任务进入任务队列,等待有线程空闲就执行

public static ExecutorService newSingleThreadExecutor() :创建一个只有一个线程的线程池,每次有新任务,若线程空闲则执行,不空闲进入队列,等待空闲

public static ExecutorService newCachedThreadPool():创建一个不固定线程数量的线程池,每次有新任务,若线程空闲则执行,不空闲就新创建一个线程进行执行

可以看到这个创建线程池的方法返回的都是ExecutorService对象,也叫线程池对象

(2)java.util.concurrent.ExecutorService

ExecutorService是一个接口,实现了Executor接口,ExecutorService这个接口中提供submit(Runnable task)这个方法,用于提交任务。shutdown()方法,关闭线程池

(3)java.util.concurrent.Executor

这个接口只有一个方法void execute(Runnable command)也是用于提交Runnable对象(任务)

(4)java.util.concurrent.ThreadPoolExecutor

在Executors类中的创建线程池的方法,都是包裹着ThreadPoolExecutor类创建线程池对象的方法,以newFixedThreadPool(int nThread)方法为例,这个方法的源代码如下:

扫描二维码关注公众号,回复: 2586833 查看本文章

也就是创建线程池的内部实现是在ThreadPoolExecutor类中。下面我们将详细分析线程池实现的原理


核心线程池的实现原理

在ThreadPoolExecutor类中通过构造方法来创建线程池,有如下几个重载方法

以最后一个为例分析线程池参数的含义

  public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

 corePoolSize:线程池中目前的线程数

maximumPoolSize:线程池中最大允许的线程数

keepAliveTime:当线程池中的线程数大于 corePoolSize,空闲线程的存活时间

unit:存活时间的单位,比如TimeUnit.SENCOND

workQueue:任务的提交队列,若没有空余线程,任务进入这个队列

threadFactory:线程创建工厂,线程池已有的线程就是通过这个工厂创建的,一般使用默认工厂

handler:拒绝策略,当线程池池中的线程数大于最大线程数,拒绝新任务的策略

那么比如newFixedThreadPool(int nThread)其实就是让corePoolSize=maximumPoolSize来实现固定线程数量的线程池


 实例演示线程池的用法:

package xidian.lili.threadpool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolDemo {
	public static class myTask implements Runnable{
		@Override
		public void run() {
			System.out.println(System.currentTimeMillis()+":"+Thread.currentThread().getId()+"thread");
			try {
				Thread.sleep(1000);//每个线程停顿1秒
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}	
	}
	public static void main(String[] args) {
		myTask  task=new myTask ();
		//创建线程池,有5个线程
		ExecutorService exec=Executors.newFixedThreadPool(5);
		//提交10个任务
		for(int i=0;i<10;i++){
			exec.submit(task);
		}
		exec.shutdown();//关闭线程池
	}
}

 思想(1)创建Runnable对象(任务)

         (2)提交给线程池

我们newFixedThreadPool(5)创建5个线程大小的线程池,提交10个任务,5个线程一次运行然后再一起复用,时间刚好相差一秒

 

 

猜你喜欢

转载自blog.csdn.net/wangdongli_1993/article/details/81252908