线程池的原理以及实现线程池的类ExecutorService中方法的使用
1.线程池:
线程池就是就像一个容器,而这个容器就是用来存放线程的,且有固定的容量。
如果没有线程池,当需要一个线程来执行任务时就需要创建一个线程,我们设创建线程的时间为t1,执行线程的时间为t2,销毁线程的时间为t3。每次创建线程到线程销毁时间是t1+t2+t3而线程池技术会将t1和t3时间的操作安排在在服务器程序的启动和结束的时间段或者一些空闲的时间段并且线程池中会始终保持有其容量大小的线程存在,当需要使用线程时就从线程池中调用,这大大节省了资源,提高了效率。
线程池详解参考: http://blog.csdn.net/hsuxu/article/details/89859312.ExecutorService
ExecutorService service= Executors.newFixedThreadPool(100);
方法:
execute(Runnable)
接收一个Runnable对象作为参数,并且以异步的方式执行他,但是这和执行后不会返回执行后的结果
submit(Runnable)
同样接收一个runnable对象作为参数,但是会返回一个Future 对象。这個 Future 对象可以用于判断 Runnable 是否结束执行。
扩展
future对象的使用及作用:简单来说就是当我们需要某一个线程A的执行结果(即要想进行下一步操作必须要A这一线程执行完毕)才能继续执行接下来的操作时,一般的runnable方法只能调用join方法阻塞主线程B来等待线程A执行完毕,这样就造成了时间浪费无法体现多线程的优势,而使用future可以在执行线程A时同时异步执行其他不需要A的结果的线程,且可以时刻返回线程A的执行状态,看A是否执行完毕
例子:
假如你突然想做饭,但是没有厨具,也没有食材。网上购买厨具比较方便,食材去超市买更放心。
实现分析:在快递员送厨具的期间,我们肯定不会闲着,可以去超市买食材。所以,在主线程里面另起一个子线程去网购厨具。我们要想做菜,必须要厨具和食材都齐全才能开始,若购买厨具是最耗时的环节,我们不调用join方法等待购买厨具线程执行完毕就会出现厨具还没买到就开始做菜的错误所以若使用runnable方法我们只能等待购买厨具这个线程执行完毕才能执行其他方法,而使用future对象,我们就可以在购买厨具的同时进行食材的购买
具体实现及功能看文章:https://www.cnblogs.com/cz123/p/7693064.html
Callable对象:
submit(Callable) 和方法 submit(Runnable) 比较类似,但是区别则在于它们接收不同的参数类型。Callable 的实例与 Runnable 的实例很类似,但是 Callable 的 call() 方法可以返回一个结果。方法 Runnable.run() 则不能返回结果。Callable 的返回值可以从方法 submit(Callable) 返回的 Future 对象中获取。
invokeAny(...)
invokeAll(...)
shutdown():不会立即终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务
shutdownNow():立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务
isTerminated方法:判断所有子线程是否全部执行完毕并关闭,如果全部执行完毕则返回true。注意除非首先调用shutdown或shutdownNow,否则isTerminated永不为true。
若关闭后所有任务都已完成,则返回true。
详解参考:http://blog.csdn.net/bairrfhoinn/article/details/16848785