public static ExecutorSevice newSingleThreadExecutor()
public static ExecutorSevice newFixedThreadPool()
public static ExecutorSevice newCachedThreadPool()
public static ScheduledExecutorService newScheduledThreadPool()
public static ExecutorService newWorkStealingPool()
new ForkJoinPool()
newCachedThreadPool() :创建一个 ExecutorService,该 ExecutorService 根据需要来创建线程,可以重复利用已存在的线程来执行任务。
newFixedThreadPool(int numberOfThreads) :创建一个可重复使用的、固定线程数量的 ExecutorService。
newScheduledThreadPool(int corePoolSize):根据时间计划,延迟给定时间后创建 ExecutorService(或者周期性地创建 ExecutorService)。
newSingleThreadExecutor():创建单个工作线程 ExecutorService。
newSingleThreadScheduledExecutor():根据时间计划延迟创建单个工作线程 ExecutorService(或者周期性的创建)。
newWorkStealingPool():创建一个拥有多个任务队列(以便减少连接数)的 ExecutorService
new ForkJoinPool() 并行地实现分治算法
newSingleThreadExecutor()和newFixedThreadPool(1)有什么区别呢?
上面说了那么多,答案应该也很显而易见了,实际上差别仅仅在于newSingleThreadExecutor()返回的线程池少暴露了一些方法并且多了个finalize方法保证线程池调用shutdown(),仅此而已。
网上有一些错误的回答,比如说前者线程执行期间抛出异常仍然能保证又其他线程顶替他,而后者不行,这样的回答都是错的。想要论证这是错的实际上很简单,对newFixedThreadPool(1)进行测试:
-
package newFixedThreadPool;
-
import java.util.concurrent.ExecutorService;
-
import java.util.concurrent.Executors;
-
public class Test {
-
public static void main(String[] args) {
-
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(1);
-
int i = 0;
-
while (i++<10) {
-
final int index = i;
-
fixedThreadPool.execute(new Runnable() {
-
@Override
-
public void run() {
-
if(index == 1){
-
throw new IllegalStateException("handler exception");//线程运行时抛出异常
-
}
-
System.out.println(Thread.currentThread().getName() + "执行");
-
try {
-
Thread.sleep(3000);//模拟当前线程执行其他操作 花费3s
-
} catch (InterruptedException e) {
-
e.printStackTrace();
-
}
-
}
-
});
-
}
-
fixedThreadPool.shutdown();
-
}
-
}
运行结果如下:
可以看到对于newFixedThreadPool(1),当一个线程在运行时抛出异常也会有其他线程顶替他去完成接下来的任务。
接下来对newSingleThreadExecutor()方法进行测试:
-
package newSingleThreadExecutor;
-
import java.util.concurrent.ExecutorService;
-
import java.util.concurrent.Executors;
-
public class Test {
-
public static void main(String[] args) {
-
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
-
int i = 0;
-
while (i++ < 10) {
-
final int index = i;
-
singleThreadExecutor.execute(new Runnable() {
-
@Override
-
public void run() {
-
if(index == 1){
-
throw new IllegalStateException("handler exception");
-
}
-
System.out.println(Thread.currentThread().getName() + "执行" + "No." + index);
-
}
-
});
-
}
-
singleThreadExecutor.shutdown();
-
}
-
}
执行结果如下:
对于newSingleThreadExecutor()来说,也是当线程运行时抛出异常的时候会有新的线程加入线程池替他完成接下来的任务。
1. LinkedBlockingQueue
无界队列。可以一直添加任务,直到内存溢出。
2. SynchronousQueue
没有容量的队列。一个任务都不能放进去。
3. DelayedWorkQueue
延迟工作的队列。
4. WorkQueue
支持工作窃取的队列。
1. void execute(Runnable command);
直接提交,没有返回值。
2. <T> Future<T> submit(Callable<T> task);
任务有返回值,通过 Future 获得返回值。
3. Future<?> submit(Runnable task)
任务没有返回值,任务完成后,通过 Future 得到的是 null。