一:为什么要使用线程池?什么时候该使用线程池?
主要有一下几点原因:一、创建一个新的线程是有一定的代价的;二、如果在一个程序中创建大量的线程的话,
这会大大的降低程序的性能有时候甚至会导致虚拟机崩溃,所以就有必要去固定当前前程的数量以限制并发线程的数量,而线程
池就刚好具有此功能,一个线程池中包含许多准备运行的空闲线程,当将任务以Runnable或Callable的对象形式交给线程池后,
线程池就会从中找到一个空闲的线程去运行此任务,而当run方法退出时,该线程也不会自动死亡,而是在池中准备为下一个任务
请求提供服务。这样就能用线程池去自动管理当前的线程,而且控制并发线程的数量。
----------------YYC
以上也就是说当我们的程序需要去大量的俄而且生命周期很短的线程时,就需要去用到线程池。
二、创建线程池的方法
在JAVA的Executors类中有这很多静态工厂的方法来得到一个线程池,其中相主要的几种方法分别是:
Executors.newCache的ThreadPool()//得到一个线程池,对于每一个任务请求,如果有空闲的线程则
立即执行,否则就会创建一个新的线程。
newFixedThreadPool()//创建一个有固定大小的线程池。对于如果请求任务的数目大于了当前空闲的
线程数,这让多余的任务进入等待队列等待有空闲线程后再运行
newSingleThreadExecutor()//是一个单线程的线程池,里面始终只有一个线程,所以对于提交给他的
任务将会按照顺序一个一个的接着完成。
三、将Runnable或Callable任务提交给线程池的方法
Future<?> submit(Runnable task) //此时Future对对象的get()方法将不再有用,只会返回一个null。
Future<T> submit(Runnable task,T result)
Future<T> submit(Callable<T> task)
其中的三个方法都返回了一个Future对象,用来对这个线程的运行状态加以控制和获取。
四、关闭线程池
关闭线程池的方法也都两个,分别是:
shutdown()// 启动线程池的关闭序列,该线程池将不会再接受任务请求,而且会在等待正在运行的所有线程
运行结束后,杀死所有线程。
shutdownNow()//该方法将取消尚未开始的所有任务,并立即终止正在运行的线程,自行灭亡。
五、具体应用实例如下:
For Example:
/**
* 定义一个任务类,实现Callable接口
*/
public static class MyCallableClass implements Callable<String>{
private int value = 0;
public MyCallableClass(int flag){
this.value = flag;
}
public String call() throws Exception{
if (this.value == 0){
// 如果value的值为0,则立即返回
return "value = 0";
}
if (this.value == 1){
// 如果value的值为1,做一个无限循环
try {
while (true) {
System.out.println("looping.");
Thread.sleep(2000);
}
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
return "false";
} else {
// value不为0或者1,则抛出异常
throw new Exception("Invalid value!");
}
}
}
开启线程
case R.id.button3:
// 定义3个Callable类型的任务
MyCallableClass task1 = new MyCallableClass(0);
MyCallableClass task2 = new MyCallableClass(1);
MyCallableClass task3 = new MyCallableClass(2);
// 创建一个执行任务的服务
ExecutorService es = Executors.newFixedThreadPool(3);
try {
// 提交并执行任务,任务启动时返回了一个 Future对象,
// 如果想得到任务执行的结果或者是异常可对这个Future对象进行操作
Future future1 = es.submit(task1);
// 获得第一个任务的结果,如果调用get方法,当前线程会等待任务执行完毕后才往下执行
System.out.println("task1: " + future1.get());
Future future2 = es.submit(task2);
// 等待5秒后,再停止第二个任务。因为第二个任务进行的是无限循环
Thread.sleep(5000);
//执行该语句时会中断异常,并在线程内部被捕捉
System.out.println("task2 cancel: " + future2.cancel(true));
// 获取第三个任务的输出,因为执行第三个任务会引起异常
// 所以下面的语句将引起异常的抛出
Future future3 = es.submit(task3);
System.out.println("task3: " + future3.get());
//会产生执行异常
} catch (Exception e){
System.out.println(e.toString());
}
// 停止任务执行服务
es.shutdownNow();
break;