我们之前创建一个线程的时候,就是直到new一个Thread创建一个线程,但是在jdk1.5之后,Java为我们提供了一个Java.util.concurrent包,这个包下有Executor接口,这就为我们提供了线程池的方法去开启多个线程,那么说到这里我们是不是会问:为什么要用Executor呢?或者new的方式有什么缺点呢?
1)每次我们new Thread都会创建一个对象,不能被重用,而且对象的创建和销毁也是消耗资源的;
2)new Thread我们没法去设置定时、线程中断等功能;
3)new Thread缺乏统一的管理,我们new多了的时候,就会出现线程之间的竞争,或者占用过多的cpu资源,甚至可能导致死机;
那么反过来Executor肯定能解决这些问题,所以使用线程池更加有利;那么我们来看一下Executor:
查看源码我们可以看到Executor接口其实很简单,就一个方法:
public interface Executor {
/**
* Executes the given command at some time in the future. The command
* may execute in a new thread, in a pooled thread, or in the calling
* thread, at the discretion of the {@code Executor} implementation.
*
* @param command the runnable task
* @throws RejectedExecutionException if this task cannot be
* accepted for execution
* @throws NullPointerException if command is null
*/
void execute(Runnable command);
}
而ExecutorService接口继承了Executor接口,是Executor的扩展子接口;
这算他们之间的第一个区别,
而第二个区别是,Executor中的execute接口的是实现Runable接口的对象;而ExecutorService中的submit接收的实现Runable接口的对象或者callable接口的对象;
第三个区别是:Executor中的execute方法没有返回值,而submit方法有future返回值;
第四个区别是:ExecutorService还提供了控制线程池的方法;
这里说一下注意点:那就是ExecutorService的submit方法获取返回值get获取数据的时候,会导致get所在的线程发生堵塞,直到你返回值的线程执行完后,get线程才获取最终的结果;
ExecutorService为我们提供了四种线程池:
1)newCachedThreadPool线程池;
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer