java5线程池详解与Executors类创设不同线程池的用法

java5线程池详解与Executors类创建不同线程池的用法

java中的线程池是非常重要的,它可以节省资源开销,从而提升程序的性能。向Tomcat等一些web服务器都必须用到线程池。java5中为我们提供了一些应用线程池的API,下面的代码将详解其用法。


package hxl.insist;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class DifferentKindsThreadPool {

	public static void main(String[] args) {
		displayThreadPool();
		displayCachedThreadPool();
		displaySingleThreadPool();
		displayScheduledThreadPool();
	}
	
	/**
	 * 创建一个定时任务的线程池
	 */
	public static void displayScheduledThreadPool() {
		ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4);
		//它可以向固定线程池一样执行任务
		distributeTaskForThreadPool(scheduledThreadPool);
		//这是它的特殊之处,可以定时任务
		scheduledThreadPool.schedule(
				new Runnable() {
					@Override
					public void run() {
						System.out.println("开始执行任务1");
					}
				}, 
				5, 
				TimeUnit.SECONDS);
		//每隔2秒再次重新执行任务
		scheduledThreadPool.scheduleAtFixedRate(
				new Runnable() {
					@Override
					public void run() {
						System.out.println("开始执行任务2");
					}
				}, 
				5, 
				3, 
				TimeUnit.SECONDS);
	}

	/**
	 * 创建只有一个线程的线程池,如果线程终止,
	 * 他将会创建一个新的线程加入到池子中,这
	 * 个线程池会保证池子中始终有一个线程
	 */
	public static void displaySingleThreadPool() {
		ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
		distributeTaskForThreadPool(singleThreadPool);
	}

	/**
	 * 创建一个可根据需要创建线程的线程池,但是
	 * 当先前创建的线程可得到时就会重用先前的线
	 * 程,如果不存在可得到的线程,一个新的线程
	 * 将被创建并被加入到池子中。60秒没有被用到
	 * 的线程将被终止并从缓存中移除
	 */
	public static void displayCachedThreadPool() {
		ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
		distributeTaskForThreadPool(cachedThreadPool);
	}

	/**
	 * 创建一个带有固定线程的线程池
	 */
	public static void displayThreadPool() {
		// 创建一个带有4个固定线程的线程池
		ExecutorService threadPool = Executors.newFixedThreadPool(4);
		distributeTaskForThreadPool(threadPool);
	}

	/**
	 * 为线程池分配8个任务,使其驱动
	 * @param threadPool
	 */
	public static void distributeTaskForThreadPool(ExecutorService threadPool) {
		// 让线程池驱动8个任务
		for (int i = 1; i <= 8; i++) {
			// 由于内部类里面不能放一个非final的变量,所以我把i的值赋予task
			final int task = i;

			threadPool.execute(new Runnable() {
				@Override
				public void run() {
					System.out.println("我是" + Thread.currentThread().getName()
							+ "," + "拿到了第" + task + "个任务,我开始执行了");
				}
			});
		}
	}
}