(1)为什么使用线程池?

  • 线程缺乏统一管理,占用过多系统资源;
  • 缺乏更多功能,如定时执行、定期执行等;

(2)使用线程池的好处?

  • 重用存在的线程,减少对象创建、消亡的开销;
  • 有效控制最大并发数,提高系统资源使用率;
  • 定时执行、定期执行;

(3)线程池所在的包:java.util.concurrent

  • 顶级接口是Executor,真正的线程池接口是ExecutorService
  • java.util.concurrent.Executors类提供创建线程池的方法
  • 线程池中的一些操作:

(4) 使用newCachedThreadPool()方法创建线程池;
创建一个可缓存的线程池,有任务时买才创建新任务

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

/** * 使用newCachedThreadPool()方法创建线程池; * 创建一个可缓存的线程池,有任务时买才创建新任务 * @Hudie */
public class Test {
	public static void main(String[] args) {
		ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

		// 在线程池中执行10个任务;
		for (int i = 0; i < 10; i++) {
			cachedThreadPool.execute(new MyRunnable(i));
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

class MyRunnable implements Runnable {
	int num;

	public MyRunnable(int num) {
		super();
		this.num = num;
	}

	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + ":" + num);
	}
}

假如关掉休眠时间

那么实现结果为:

有的线程执行完第一次任务后,闲置下来接第二个任务,而不是被销毁,没有必要再创建一个线程了。

(5)使用newSingleThreadExecutor()方法创建线程池;
创建一个单线程池;

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

/** * 使用newSingleThreadExecutor()方法创建线程池; * * @Hudie */
public class Test2 {
	public static void main(String[] args) {
		ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();

		// 在线程池中执行10个任务;
		for (int i = 0; i < 10; i++) {
			singleThreadPool.execute(new MyRunnable(i));
			// try {
			// Thread.sleep(200);
			// } catch (InterruptedException e) {
			// // TODO Auto-generated catch block
			// e.printStackTrace();
			// }
		}
	}
}

class MyRunnable implements Runnable {
	int num;

	public MyRunnable(int num) {
		super();
		this.num = num;
	}

	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + ":" + num);
	}
}

输出结果:只有一个线程在执行任务.

(6)使用过newFixedThreadPool(int nThreads)
创建一个固定长度的线程池,空闲线程会一直保留。参数nThreads设定线程池中线程的数目;

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

/** * 使用newFixedThreadPool(int nThreads)方法创建线程池; * * @Hudie */
public class Test3 {
	public static void main(String[] args) {
		ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);

		// 在线程池中执行10个任务;
		for (int i = 0; i < 10; i++) {
			fixedThreadPool.execute(new MyRunnable(i));
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

class MyRunnable implements Runnable {
	int num;

	public MyRunnable(int num) {
		super();
		this.num = num;
	}

	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + ":" + num);
	}
}

显示结果:

(7)使用newScheduledThreadPool()方法创建线程池
可以延时,定时执行任务的线程池

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

/** * 使用newScheduledThreadPool()方法创建线程池; * 可以延时,定时执行任务的线程池; * @Hudie */
public class Test4 {
	public static void main(String[] args) {
		ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);
		System.out.println("***********开始执行**********");
		scheduledThreadPool.scheduleAtFixedRate(new MyRunnable(), 5, 2, TimeUnit.SECONDS);
	}
}

class MyRunnable implements Runnable {

	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + "延时5s执行,每2s执行一次.");
	}
}

5s后开始执行,之后每隔2s执行一次。

(8)ThreadPoolExecutor类
自定义一个线程池

几个重要的参数:

线程池举例:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/** * 创建自定义线程池 * * @Hudie */
public class Demo1 {
	public static void main(String[] args) {
		// 创建一个自定义线程池
		ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 7, 300, TimeUnit.MILLISECONDS,
				new ArrayBlockingQueue<Runnable>(4));
		for (int i = 1; i <= 12; i++) {
			executor.execute(new MyRunnable(i));
			System.out.println("线程池中线程数:" + executor.getPoolSize() + ",队列中等待执行的任务数:" + executor.getQueue().size()
					+ ",已经执行完的任务数" + executor.getCompletedTaskCount());
		}
		executor.shutdown();
	}
}

class MyRunnable implements Runnable {
	int num;// 第几个任务

	public MyRunnable(int num) {
		super();
		this.num = num;
	}

	@Override
	public void run() {
		System.out.println("正在执行任务" + num);
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("任务" + num + "执行完毕");
	}
}