在《浅谈对java线程池的理解一》中介绍了线程池的创建,一般利用Executors类提供的方法进行创建就可满足需求了,当然如果要想进一步创建更加自定义化的线程池,可以利用ThreadPoolService的构造方法进行创建,这里不再详细介绍了,感兴趣的同学可以自行查阅API。
本篇主要讲述一下线程池的使用。我们先看一下线程池相关几个核心类的类图:
由上面类图可以看出,ExecutorService接口继承Executor接口,而ExecutorService有几个实现类,比如ScheduleExecutorService和ThreadPoolService,总而言之,我们声明的线程池都是实现了ExecutorService接口,几个重要的经常使用的方法有下面几个:
1、 execute()
该方法是线程池运行线程的方法,该方法只是发出一个自行的命令,至于什么时候线程开始运行不知道,java API的描述是“at some time in the future(在将来的某个时间)”。用法如下:
ExecutorServiceexecutorService = Executors.newSingleThreadExecutor();
Log.d("thread","beginexecute...");
executorService.execute(new Runnable(){
@Override
public void run() {
Log.d("thread","runnable is running!");
}
});
运行结果如下:
2、 submit()
该方法也是线程池执行线程的方法,和execute方法类似,但是该方法相比于execute方法的一个优点就是可以返回线程执行的结果。该方法有3种传参方式:
⑴ Future<?>submit(Runnable task)
该方法等同于execute方法
⑵Future<T>submit(Callable<T> task)
该方法的参数是一个Callable对象,用法如下例子所示:
ExecutorServiceexecutorService = Executors.newFixedThreadPool(2);
Callable<String> callable1 = newCallable<String>() {
@Override
public String call() throwsException {
Log.d("zhouyudong","call1.call"+Thread.currentThread().getName());
Thread.sleep(2000);
Log.d("zhouyudong","call1.call after sleep");
return "first over";
}
};
Callable<String> callable2 = newCallable<String>() {
@Override
public String call() throwsException {
Log.d("zhouyudong","call2.call"+Thread.currentThread().getName());
Thread.sleep(4000);
Log.d("zhouyudong","call2.call after sleep");
return "second over";
}
};
Callable<String> callable3 = newCallable<String>() {
@Override
public String call() throws Exception {
Log.d("zhouyudong","call3.call"+Thread.currentThread().getName());
// Thread.sleep(4000);
return "third over";
}
};
List<Future<String>>futureList = new ArrayList<>();
futureList.add(executorService.submit(callable1));
futureList.add(executorService.submit(callable2));
futureList.add(executorService.submit(callable3));
for(Future<String>future:futureList)
{
try {
Log.d("zhouyudong",future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
该方法可以获取任务执行结果的返回值,返回值在Future<T>中,通过get方法可以获取,但是如果线程没有执行完毕,get方法会被阻塞。
⑶Future<T>submit(Runnable task, T result)
该方法就是相当于给Runnable的run方法增加一个返回值,该返回值就是result
3、 shutdown()
该方法会把线程池的状态置为SHUTDOWN状态,分两种情况考虑,一是线程池的任务队列为空时,调用shutdown方法之后,正在执行的任务会被停止,并且不再会接受新任务;二是线程池中有等待的任务,那么调用shutdown方法后,仅有的作用就是再会接受新任务
4、 shutdownNow()
该方法会把线程池的状态置为STOP状态,并试图停止所有正在执行的线程,不再处理还在池队列中等待的任务,当然,它会返回那些未执行的任务。
5、 isShutdown()
在调用shutdown或者shutdownNow方法之后,该方法返回true。
6、 isTerminate()
当调用shutdown()或者或者shutdownNow方法后,并且所有提交的任务完成后返回为true。