使用线程池可以不用线程的时候放回线程池,用的时候再从线程池取。
1.5后引入的Executor框架的最大优点是把任务的提交和执行解耦。
Executor接口中定义了一个方法execute,该方法接收一个Runable实例,它用来执行一个任务,任务即一个实现了Runnable接口的类。
ExecutorService接口继承自Executor接口,它提供了更丰富的实现多线程的方法。比如,ExecutorService提供了关闭自己的方法,可以调用ExecutorService的shutdown()方法来关闭 ExecutorService,调用该方法后,将导致ExecutorService停止接受任何新的任务且等待已经提交的任务执行完成(已经提交的任务会分两类:一类是已经在执行的,另一类是还没有开始执行的),当所有已经提交的任务执行完毕后将会关闭ExecutorService。因此我们一般用该接口来实现和管理多线程。
ExecutorService的生命周期包括三种状态:运行、关闭、终止。创建后便进入运行状态,当调用了shutdown()方法时,便进入关闭状态,此时意味着ExecutorService不再接受新的任务,但它还在执行已经提交了的任务,当所有已经提交了的任务执行完后,便到达终止状态。如果不调用shutdown()方法,ExecutorService会一直处在运行状态,不断接收新的任务,执行新的任务,服务器端一般不需要关闭它,保持一直运行即可。
public class Thread08 {
public static void main(String[] args) {
ExecutorService es= Executors.newCachedThreadPool();//可缓存的线程池
for (int i = 0; i <5 ; i++) {
es.execute(new MyExcutor()); //给线程分配任务
System.out.println("IIIII"+i);
}
es.shutdown();//关闭线程
}
}
class MyExcutor implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"已经被调用");
}
}
Callable的call()方法只能通过ExecutorService的submit(Callable<T> task) 方法来执行,并且返回一个 <T>Future<T>,是表示任务等待完成的 Future。
submit是首先选择空闲线程来执行任务,如果没有,才会创建新的线程来执行任务。另外,需要注意:如果Future的返回尚未完成,则get()方法会阻塞等待,直到Future完成返回。
public class Thread09 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
test();
}
static void test() throws ExecutionException, InterruptedException {
//创建线程池对象
ExecutorService es= Executors.newFixedThreadPool(10); //固定数目线程的线程池
//创建容器对象管理任务的结果
ArrayList<Future<Integer>> list=new ArrayList<>();
//提交任务
for (int i = 0; i <10 ; i++) {
//10个随机任务
Callable<Integer> callable=new Callable<Integer>() {
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName()+"开始执行任务");
Thread.sleep(500);
return (int)(Math.random()*10);
}
};
//用户获得任务结果的Future的对象
Future<Integer> future=es.submit(callable);
list.add(future);
}
//获得结果
for (int i = 0; i <10 ; i++) {
System.out.println(list.get(i).get());
}
es.shutdown();//关闭线程
}
}
public class Thread11 {
public static void main(String[] args) {
ExecutorService es= Executors.newSingleThreadExecutor();
Future<Integer> future=es.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return new Random().nextInt(10);
}
});
try {
Thread.sleep(1000);
try {
System.out.println(future.get());
} catch (ExecutionException e) {
e.printStackTrace();
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
es.shutdown();
}
}
}