⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 blog.csdn.net/meism5/article/details/90261021 「meism5」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

JDK1.8 创建线程池有哪几种方式?

newFixedThreadPool

定长线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数量,这时线程数量不再变化,当线程发生错误结束时,线程池会补充一个新的线程

测试代码:

public class TestThreadPool {

//定长线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数量,这时线程数量不再变化,当线程发生错误结束时,线程池会补充一个新的线程
static ExecutorService fixedExecutor = Executors.newFixedThreadPool(3);


public static void main(String[] args) {
testFixedExecutor();
}

//测试定长线程池,线程池的容量为3,提交6个任务,根据打印结果可以看出先执行前3个任务,3个任务结束后再执行后面的任务
private static void testFixedExecutor() {
for (int i = 0; i < 6; i++) {
final int index = i;
fixedExecutor.execute(new Runnable() {
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " index:" + index);
}
});
}

try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("4秒后...");

fixedExecutor.shutdown();
}

}

打印结果:

pool-1-thread-1 index:0
pool-1-thread-2 index:1
pool-1-thread-3 index:2
4秒后...
pool-1-thread-3 index:5
pool-1-thread-1 index:3
pool-1-thread-2 index:4

newCachedThreadPool

可缓存的线程池,如果线程池的容量超过了任务数,自动回收空闲线程,任务增加时可以自动添加新线程,线程池的容量不限制

测试代码:

public class TestThreadPool {

//可缓存的线程池,如果线程池的容量超过了任务数,自动回收空闲线程,任务增加时可以自动添加新线程,线程池的容量不限制
static ExecutorService cachedExecutor = Executors.newCachedThreadPool();


public static void main(String[] args) {
testCachedExecutor();
}

//测试可缓存线程池
private static void testCachedExecutor() {
for (int i = 0; i < 6; i++) {
final int index = i;
cachedExecutor.execute(new Runnable() {
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " index:" + index);
}
});
}

try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("4秒后...");

cachedExecutor.shutdown();
}

}

打印结果:

pool-1-thread-1 index:0
pool-1-thread-6 index:5
pool-1-thread-5 index:4
pool-1-thread-4 index:3
pool-1-thread-3 index:2
pool-1-thread-2 index:1
4秒后...

newScheduledThreadPool

定长线程池,可执行周期性的任务

测试代码:

public class TestThreadPool {

//定长线程池,可执行周期性的任务
static ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(3);


public static void main(String[] args) {
testScheduledExecutor();
}

//测试定长、可周期执行的线程池
private static void testScheduledExecutor() {
for (int i = 0; i < 3; i++) {
final int index = i;
//scheduleWithFixedDelay 固定的延迟时间执行任务;scheduleAtFixedRate 固定的频率执行任务
scheduledExecutor.scheduleWithFixedDelay(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName() + " index:" + index);
}
}, 0, 3, TimeUnit.SECONDS);
}

try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("4秒后...");

scheduledExecutor.shutdown();
}

}

打印结果:

pool-1-thread-1 index:0
pool-1-thread-2 index:1
pool-1-thread-3 index:2
pool-1-thread-1 index:0
pool-1-thread-3 index:1
pool-1-thread-1 index:2
4秒后...

newSingleThreadExecutor

单线程的线程池,线程异常结束,会创建一个新的线程,能确保任务按提交顺序执行

测试代码:

public class TestThreadPool {

//单线程的线程池,线程异常结束,会创建一个新的线程,能确保任务按提交顺序执行
static ExecutorService singleExecutor = Executors.newSingleThreadExecutor();


public static void main(String[] args) {
testSingleExecutor();
}

//测试单线程的线程池
private static void testSingleExecutor() {
for (int i = 0; i < 3; i++) {
final int index = i;
singleExecutor.execute(new Runnable() {
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " index:" + index);
}
});
}

try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("4秒后...");

singleExecutor.shutdown();
}

}

打印结果:

pool-1-thread-1 index:0
4秒后...
pool-1-thread-1 index:1
pool-1-thread-1 index:2

newSingleThreadScheduledExecutor

单线程可执行周期性任务的线程池

测试代码:

public class TestThreadPool {

//单线程可执行周期性任务的线程池
static ScheduledExecutorService singleScheduledExecutor = Executors.newSingleThreadScheduledExecutor();


public static void main(String[] args) {
testSingleScheduledExecutor();
}

//测试单线程可周期执行的线程池
private static void testSingleScheduledExecutor() {
for (int i = 0; i < 3; i++) {
final int index = i;
//scheduleWithFixedDelay 固定的延迟时间执行任务;scheduleAtFixedRate 固定的频率执行任务
singleScheduledExecutor.scheduleAtFixedRate(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName() + " index:" + index);
}
}, 0, 3, TimeUnit.SECONDS);
}

try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("4秒后...");

singleScheduledExecutor.shutdown();
}

}

打印结果:

pool-1-thread-1 index:0
pool-1-thread-1 index:1
pool-1-thread-1 index:2
pool-1-thread-1 index:0
pool-1-thread-1 index:1
pool-1-thread-1 index:2
4秒后...

newWorkStealingPool

任务窃取线程池,不保证执行顺序,适合任务耗时差异较大。

线程池中有多个线程队列,有的线程队列中有大量的比较耗时的任务堆积,而有的线程队列却是空的,就存在有的线程处于饥饿状态,当一个线程处于饥饿状态时,它就会去其它的线程队列中窃取任务。解决饥饿导致的效率问题。

默认创建的并行 level 是 CPU 的核数。主线程结束,即使线程池有任务也会立即停止。

测试代码:

public class TestThreadPool {

//任务窃取线程池
static ExecutorService workStealingExecutor = Executors.newWorkStealingPool();

public static void main(String[] args) {
testWorkStealingExecutor();
}

//测试任务窃取线程池
private static void testWorkStealingExecutor() {
for (int i = 0; i < 10; i++) {//本机 CPU 8核,这里创建10个任务进行测试
final int index = i;
workStealingExecutor.execute(new Runnable() {
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " index:" + index);
}
});
}

try {
Thread.sleep(4000);//这里主线程不休眠,不会有打印输出
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("4秒后...");

// workStealingExecutor.shutdown();
}

}

打印结果如下,index:8,index:9并未打印出:

ForkJoinPool-1-worker-1 index:0
ForkJoinPool-1-worker-7 index:6
ForkJoinPool-1-worker-5 index:4
ForkJoinPool-1-worker-3 index:2
ForkJoinPool-1-worker-4 index:3
ForkJoinPool-1-worker-2 index:1
ForkJoinPool-1-worker-0 index:7
ForkJoinPool-1-worker-6 index:5
4秒后...

文章目录
  1. 1. newFixedThreadPool
  2. 2. newCachedThreadPool
  3. 3. newScheduledThreadPool
  4. 4. newSingleThreadExecutor
  5. 5. newSingleThreadScheduledExecutor
  6. 6. newWorkStealingPool