上一篇文章我们一起学习了关于【线程池的使用规范、线程池的7个参数、4种拒绝策略、线程池的5种状态、线程池的执行流程】,接下来我们来学习一下:【线程池有哪几种创建方式,能详细的说下吗?俩种方式、7种方法?以及案例演示过程】
线程池的创建方法总共有 7 种(其中 6 种是通过 Executors 创建的,1 种是通过ThreadPoolExecutor 创建的,但总体来说可分为 2 类):
JDK 8 添加
。创建一个固定大小的线程池,可控制并发的线程数,超出的线程会在队列中等待。
案例代码如下:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
fixedThreadPool();
}
public static void fixedThreadPool() {
// 创建固定个数大小的线程池
ExecutorService threadPool = Executors.newFixedThreadPool(3);
// 创建任务
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("当前任务已经被线程"+Thread.currentThread().getName()+"执行了");
}
};
// 补充一下:执行任务的方法有两种:submit 和 execute
// 执行方式 1:submit
threadPool.submit(runnable);
// 执行方式 2:execute
threadPool.execute(runnable);
}
}
创建一个可缓存的线程池,若线程数超过处理所需,缓存一段时间后会回收,若线程数不够,则新建线程;
案例代码如下:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
cachedThreadPool();
}
public static void cachedThreadPool() {
// 创建线程池
ExecutorService threadPool = Executors.newCachedThreadPool();
// 执行任务
for (int i = 0; i < 10; i++) {
threadPool.execute(() -> {
System.out.println("当前任务已经被线程"+Thread.currentThread().getName()+"执行了");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
}
}
创建单个线程数的线程池,它可以保证先进先出的执行顺序;
案例代码如下:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
singleThreadExecutor();
}
public static void singleThreadExecutor() {
// 创建线程池
ExecutorService threadPool = Executors.newSingleThreadExecutor();
// 执行任务
for (int i = 0; i < 10; i++) {
final int id = i;
threadPool.execute(() -> {
System.out.println("线程"+Thread.currentThread().getName()+"执行了此时的任务:"+id);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
}
}
创建一个可以执行延迟任务的线程池。
案例代码如下:
import java.time.LocalDateTime;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
scheduledThreadPool();
}
public static void scheduledThreadPool() {
// 创建线程池
ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(5);
// 添加定时执行任务(3s 后执行)
System.out.println("线程池执行添加任务的操作,此时时间为:" + LocalDateTime.now());
threadPool.schedule(() -> {
System.out.println("线程池执行运行任务的操作,此时时间为:" + LocalDateTime.now());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, 3, TimeUnit.SECONDS);
}
}
创建一个单线程的可以执行延迟任务的线程池;
案例代码如下:
import java.time.LocalDateTime;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
SingleThreadScheduledExecutor();
}
public static void SingleThreadScheduledExecutor() {
// 创建线程池
ScheduledExecutorService threadPool = Executors.newSingleThreadScheduledExecutor();
// 添加定时执行任务(5s 后执行)
System.out.println("线程池执行添加任务的操作,此时时间为:" + LocalDateTime.now());
threadPool.schedule(() -> {
System.out.println("线程池执行运行任务的操作,此时时间为:" + LocalDateTime.now());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, 5, TimeUnit.SECONDS);
}
}
创建一个抢占式执行的线程池,任务执行顺序不确定。JDK 8 添加
。
案例代码如下:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
workStealingPool();
}
public static void workStealingPool() {
// 创建线程池
ExecutorService threadPool = Executors.newWorkStealingPool();
// 执行任务
for (int i = 0; i < 10; i++) {
final int id = i;
threadPool.execute(() -> {
System.out.println("线程"+Thread.currentThread().getName()+"执行了此时的任务:"+id);
});
}
// 确保线程池中的任务执行完成
while (!threadPool.isTerminated()) {
}
}
}
案例实现代码
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
// 创建线程池
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(4, 8, 100, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
// 执行任务
for (int i = 0; i < 10; i++) {
final int id = i;
threadPool.execute(() -> {
System.out.println("线程"+Thread.currentThread().getName()+"执行了此时的任务:"+id);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
}
}
这篇文章我们学习了以下的内容:
学习编程一定要动手实操,先学习别人的东西,熟练了再演化为自己的知识。
我是硕风和炜,我们下篇文章见哦。