java线程池理解与使用

1、常用的四种线程池

Executors类中提供的几个静态方法来创建线程池:

  • newCachedThreadPool 缓存线程池
  • newFixedThreadPool 固定线程数线程池
  • newSingleThreadExecutor 单线程线程池
  • newScheduledThreadPool 定时和周期性任务执行的定长线程池

2、线程池的说明及使用

  • newCachedThreadPool

        创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。大小最大可以达到Integer.MAX_VALUE。源码如下:


  • newFixedThreadPool

创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。源码如下:

  • newSingleThreadExecutor

创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。源码如下:

  • newScheduledThreadPool

创建一个定长线程池,支持定时及周期性任务执行。源码如下:

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




3、线程池在java中的使用

package com.yw.thread;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MyThreadPool {
	
	private static Integer THREAD_POOL_NUM = 50;
	
	public static void main(String[] args) throws Exception{
		
		List<String> list = new ArrayList<String>();
		list.add("章程");
		list.add("流苏");
		list.add("漾须");
		
		Map<String, String> map = new HashMap<String, String>();
		
                //使用newCachedThreadPool作为示例
		ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
		//ExecutorService fixedThreadPool = Executors.newFixedThreadPool(MyThreadPool.THREAD_POOL_NUM);
		//ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
		//ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(MyThreadPool.THREAD_POOL_NUM);
		
		for (int i=0; i<10; i++) {
			cachedThreadPool.execute(new testFor(list, map));
		}
		cachedThreadPool.shutdown();
		while (true) {
			if (cachedThreadPool.isTerminated()) {
				System.out.println("多线程执行完毕");
				break;
			}
			Thread.sleep(200);
		}
		System.out.println("执行完毕===========================");
		System.out.println(map.toString());
	}
}


class testFor implements Runnable{
	
	private List<String> list;
	
	private Map<String, String> map;
	
	public testFor(List<String> list, Map<String, String> map) {
		this.list = list;
		this.map = map;
	}

	@Override
	public void run() {
		for (int i = 0; i < list.size(); i++) {
			System.out.println(Thread.currentThread().getName()+"="+list.get(i));
			map.put(Thread.currentThread().getName()+ "----" + i, list.get(i));
		}
	}
}

4、ThreadPoolExecutor类

从上面源码可以看到,Executor提供的四个创建线程池的静态方法中,最终都是调用ThreadPoolExecutor的构造函数来实现,下面就来介绍一下ThreadPoolExecutor

  • 首先介绍下各个类的关系:



java.uitl.concurrent.ThreadPoolExecutor类是线程池中最核心的一个类,它提供了四个构造方法和一个执行方法(execute):

public class ThreadPoolExecutor extends AbstractExecutorService {
	......
    public ThreadPoolExecutor(int corePoolSize,                  
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             threadFactory, defaultHandler);
    }

   
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              RejectedExecutionHandler handler) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), handler);
    }

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
    }
  ......
}

构造器中各个参数的含义:

  • corePoolSize:核心池大小。在创建线程池后,默认情况下,线程池中没有任何线程,等待有任务来了才创建线程去执行任务,除非调用了prestartAllCoreThreads()或者怕热startCoreThread()方法,这个两个方法就是与创建线程的意思,即在没有任务来之前就创建corePoolSize个线程或一个线程。当线程池中的线程数目达到corePoolSize后,就会把到达的线程任务放到缓存队列中。
  • maximumPoolSize:线程池最大线程数。表示在线程池中最多能创建多少个线程。
  • keepAliveTime:线程没有任务执行时最多保持多久时间会终止。时间单位参考unit。
  • unit:参数keepAliveTime的时间单位,有7种取值,TimeUnit类中有7种静态属性。
    TimeUnit.NANOSECONDS;       //纳秒
    TimeUnit.MICROSECONDS;      //微妙
    TimeUnit.MILLISECONDS;      //毫秒
    TimeUnit.SECONDS;           //秒
    TimeUnit.MINUTES;           //分钟
    TimeUnit.HOURS;             //小时
    TimeUnit.DAYS;               //天
  • workQueue:一个阻塞队列,用来存数等待执行的任务。一般使用LinkedBlockingQueue和Synchronous。线程池的排队策略与BlockingQueue有关
  • threadFactory:线程工厂,主要用来创建线程。
  • handler:表示当拒绝处理任务时的策略,有四种取值:
    ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。 
    ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。 
    ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
    ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务 


参考资料:

http://www.cnblogs.com/dolphin0520/p/3932921.html

猜你喜欢

转载自blog.csdn.net/yanweihpu/article/details/80102007