1、Executor
- Executor的相关关系图
Executors少了一个创建线程池的方法newScheduledThreadPool()
- 继承和实现关系
public interface ExecutorService extends Executor {}
public abstract class AbstractExecutorService implements ExecutorService {}
public interface ScheduledExecutorService extends ExecutorService {}
public class ThreadPoolExecutor extends AbstractExecutorService {}
public class ScheduledThreadPoolExecutor extends ThreadPoolExecutor implements ScheduledExecutorService {}
代码语言:javascript复制区别:
1.ExecutorService 接口继承了Executor 接口,是Executor 的子接口。
2.Executor接口中定义了execute()方法,用来接收一个Runnable接口的对象,
而ExecutorService接口中定义的submit()方法可以接收Runnable和Callable接口对象。
3.Executor接口中execute()方法不返回任何结果,而ExecutorService接口中submit()方法可以通过一个 Future 对象返回运算结果。
4.Executor和ExecutorService除了允许客户端提交一个任务,ExecutorService 还提供用来控制线程池的方法。
比如:调用 shutDown() 方法终止线程池。
5.Executors 类提供工厂方法用来创建不同类型的线程池。比如:
newSingleThreadExecutor() 创建一个只有一个线程的线程池,
newFixedThreadPool(int numOfThreads)来创建固定线程数的线程池,
newCachedThreadPool()创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newScheduledThreadPool(int corePoolSize) 创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。
- Executors简介
- Executors 是一个工厂类,其提供的是Executor、ExecutorService、ScheduledExecutorService、ThreadFactory 和 Callable 类的实例的工厂方法;
- 提供常用配置的 ExecutorService、ScheduledExecutorService的实现方法;
- 创建并返回 ThreadFactory 的方法,它可将新创建的线程设置为已知的状态。
- 将其他非Callable接口的其他类对象,封装成Callable,从而用于默些方法;
2、创建线程池
上面图例和补充里有创建线程池的四种方式。
1. newCachedThreadPool(创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。线程池为无限大)
代码语言:javascript复制 public static void main(String[] args) {
// 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
Executor cachedThreadPool = Executors.newCachedThreadPool();
// 循环10次
for (int i = 0; i < 10; i ) {
// 初始化index作为线程内输出,要求final
final int index = i;
// 等待,让前一个线程执行完成
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 执行任务
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
// 输出线程名称
System.out.println(index " 线程名称:" Thread.currentThread().getName());
}
});
}
}
结果:
可以看到使用的一个线程进行的输出,证明在线程执行完成后会被回收重新执行安排的任务
2. newFixedThreadPool(创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。)
代码语言:javascript复制 public static void main(String[] args) {
// 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i ) {
final int index = i;
fixedThreadPool.execute(new Runnable() {
public void run() {
try {
System.out.println(index);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
fixedThreadPool.shutdown();
}
结果:
我们给定长线程池设置了3个线程,就一直是这三个线程在跑
3. newScheduledThreadPool(创建一个定长线程池,支持定时及周期性任务执行。)
代码语言:javascript复制 public static void main(String[] args) {
// 创建一个定长线程池,支持定时及周期性任务执行。
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
for (int i = 0; i < 10; i ) {
scheduledThreadPool.schedule(new Runnable() {
public void run() {
System.out.println("delay 3 seconds " Thread.currentThread().getName());
}
}, 3, TimeUnit.SECONDS);// 3s以后执行
}
scheduledThreadPool.shutdown();
}
结果:
线程池有5个线程,并且在启动后3s后才去执行内容
4.newSingleThreadExecutor (按顺序来执行线程任务 但是不同于单线程,这个线程池只是只能存在一个线程,这个线程死后另外一个线程会补上,继续按顺序执行任务。)
代码语言:javascript复制public static void main(String[] args) {
/**
* 单线程化的线程池
*/
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i ) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName("Thread i = " index);
System.out.println(Thread.currentThread().getName() " index = " index);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println("ssss");
}
}
});
}
singleThreadExecutor.shutdown();
System.out.println("on the main thread...");
}