Executors类,提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService接口。
-> public static ExecutorService newFixedThreadPool(int nThreads)
创建固定数目线程的线程池。
-> public static ExecutorService newCachedThreadPool()
创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。
-> public static ExecutorService newSingleThreadExecutor()
创建一个单线程化的Executor。
-> public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。
如上方法中的线程池中的线程 会在 首次添加任务后,才会创建,创建后会一直存在(newCachedThreadPool除外),无论Runable中的任务是否已经完成了。如:newFixedThreadPool创建了一个大小为3的线程池,添加了两个任务,则只先创建两个线程。
示例用法:
Executor executors = Executors.newSingleThreadExecutor();
executors.execute(new Runnable() {
@Override
public void run() {}
});
ExecutorService类:扩展了Executor并添加了一些生命周期管理的方法。
可以看到,ExecutorService新加了如下方法:
Executor的生命周期:
有三种状态,运行 ,关闭 ,终止 。
运行:Executor创建时处于运行状态。
关闭:当调用ExecutorService.shutdown()后,处于关闭状态,isShutdown()方法返回true。这时,不应该再向Executor中添加任务,静待所有已添加的任务执行完毕,Executor才处于终止状态,isTerminated()返回true。
终止:有两种情况,一种: 在调用shutdown()后,等待所有任务完成后,就会终止;另一种:在调用shutdownNow()后,就会强行结束池中所有线程。
->shutdown()
关闭Executor,注意此关闭并不代表Executor被彻底终止了,只是标记为关闭状态,不再接收新的线程任务,静待运行中的线程运行完 才终止。如果Executor处于关闭状态,往Executor提交任务会抛出unchecked exception RejectedExecutionException。
->shutdownNow() : List<Runnable>
向线程池中所有的线程发出中断(interrupted), 这时各个线程会抛出InterruptedException异常(前提是线程中运行了sleep等会抛出异常的方法),终止Executor
->isShutdown() :boolean
判断Executor是否已经被关闭,当调用ExecutorService.shutdown()后,处于关闭状态,isShutdown()方法返回true
->isTerminated() : boolean
判断Executor是否已经终止了,在池中所有线程被关闭后,会返回true
->awaitTermination(long, TimeUnit) :boolean
会阻塞当前调用 awaitTermination() 方法的所在线程,直到 (shutdown()调用后的 所有任务已经完成)或者(超时),就会返回一个状态:true:代表当前所有任务都已经完成了,false:直到超时为止,任务都还没完成。关于awaitTermination,可参考这篇文章:https://blog.csdn.net/alinshen/article/details/78090043
->sumbit : Future
把一个Runable或Callabel 加入线程池,类似于execute() ,但sumbit可以返回一个Future,如果调用Future的get方法,会阻塞当前线程,直到任务结束。如:
ExecutorService executorService = Executors.newSingleThreadExecutor();
new Thread(new Runnable() {
@Override
public void run() {
Future future = executorService.submit(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
try {
future.get();
System.out.println("结束");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}).start();
看看 周期性的任务执行的线程池 newScheduledThreadPool :
例子:延迟5秒,每隔3秒执行一次
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
executorService.scheduleAtFixedRate(new Runnable() {
@Override public void run() {
System.out.println("正在运行,当前线程名:"+Thread.currentThread().getName());
}
}, 5000,3000, TimeUnit.MILLISECONDS);