/**
* 线程池使用案例
* 通过TheadPoolExecutor创建线程池
* TheadPoolExecutor参数:
* corePoolSize: 核心线程数 ,本例中是1
* maximumPoolSize: 最大线程数,本列中是3
* keepAliveTime: 最大存活时间,本例中是1000
* TimeUnit.MILLISECONDS: 最大存活时间的时间单位,本例中是毫秒
* 存放待处理任务的队列: 这里使用的是LinkedBlockingQueue(2),队列最大长度是2,如果没有参数,则默认是无界队列
* 线程工厂对象:本例中是new NamedThreadFactory("MyThread"),给线程池命名为"MyThread"
* 拒绝策略: 这里使用的拒绝策略是CallerRunsPolicy,当队列满了,仍有任务要放入队列时,则调用主线程来处理
* 因此同时最多只能提交 maximumPoolSize + 队列长度 的任务,本例中是3 + 2 = 5
* 如果提交任务超过了这个数量,就会启动拒绝策略
* 在本次案例中,通过输出结果发现,当提交到第6个任务时候,此时超过了 队列长度 + 最大线程数 ,
* 于是启动了拒绝策略,调用主线程来处理任务
*/
public class ThreadPoolExecutorExample {
public static void main(String[] args) {
// 创建一个固定大小为3的线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(
1, 3, 1000,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(2),
new NamedThreadFactory("MyThread"),
new ThreadPoolExecutor.CallerRunsPolicy()
);
// 提交8个任务给线程池
for (int i = 1; i <= 8; i++) {
Task task = new Task("Task " + i);
System.out.println(LocalTime.now() + " " + Thread.currentThread() + " 提交任务:" + task.getName());
executor.execute(task);
}
// 关闭线程池
executor.shutdown();
}
}
/**
* 创建任务类,实现Runnable,定义任务
*/
class Task implements Runnable {
private String name;
public Task(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public void run() {
System.out.println(LocalTime.now() + " " + Thread.currentThread().getName() + " 执行任务:" + name);
try {
Thread.sleep(2000); //模拟任务执行时间
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(LocalTime.now() +" " + Thread.currentThread().getName() + " 完成任务:" + name);
}
}
/**
* 创建线程工厂,给线程命名
*/
class NamedThreadFactory implements ThreadFactory {
private String name;
public NamedThreadFactory(String name) {
this.name = name;
}
@Override
public Thread newThread(Runnable r) {
return new Thread(r, name);
}
}
10:50:28.680 Thread[main,5,main] 提交任务:Task 1
10:50:28.681 Thread[main,5,main] 提交任务:Task 2
10:50:28.681 Thread[main,5,main] 提交任务:Task 3
10:50:28.681 Thread[main,5,main] 提交任务:Task 4
10:50:28.681 MyThread 执行任务:Task 1
10:50:28.681 Thread[main,5,main] 提交任务:Task 5
10:50:28.681 MyThread 执行任务:Task 4
10:50:28.681 Thread[main,5,main] 提交任务:Task 6
10:50:28.681 MyThread 执行任务:Task 5 //此时任务大于队列长度 + 最大线程数量,调用主线程处理任务
10:50:28.681 main 执行任务:Task 6
10:50:30.682 MyThread 完成任务:Task 4
10:50:30.682 main 完成任务:Task 6
10:50:30.682 MyThread 完成任务:Task 1
10:50:30.682 Thread[main,5,main] 提交任务:Task 7
10:50:30.682 MyThread 完成任务:Task 5
10:50:30.682 Thread[main,5,main] 提交任务:Task 8
10:50:30.682 MyThread 执行任务:Task 3
10:50:30.682 MyThread 执行任务:Task 2
10:50:30.682 MyThread 执行任务:Task 7
10:50:32.684 MyThread 完成任务:Task 3
10:50:32.684 MyThread 完成任务:Task 2
10:50:32.684 MyThread 完成任务:Task 7
10:50:32.684 MyThread 执行任务:Task 8
10:50:34.686 MyThread 完成任务:Task 8
Executor工具列创建线程方法
Executors.newFixedThreadPool()
Executors.newSingleThreadExecutor();
Executors.newCachedThreadPool();
Executors.newScheduledThreadPool();
/**
* 使用newFixedThreadPool(5)创建线程池
* 该方法创建固定大小的线程数量的线程池
* 本例中线程池中数量固定为5
*/
public class FixedThreadPoolExample {
public static void main(String[] args) {
// 创建一个固定大小的线程池,包含5个线程
ExecutorService executor = Executors.newFixedThreadPool(5);
// 提交任务给线程池
for (int i = 0; i < 10; i++) {
executor.submit(new Task(i));
}
// 关闭线程池
executor.shutdown();
}
static class Task implements Runnable {
private int taskId;
public Task(int taskId) {
this.taskId = taskId;
}
@Override
public void run() {
try {
Thread.sleep(2000); //模拟任务执行时间
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("hh:mm:ss")) + " Task " + taskId + " is running on thread " + Thread.currentThread().getName());
}
}
}
11:05:57 Task 3 is running on thread pool-1-thread-4
11:05:57 Task 2 is running on thread pool-1-thread-3
11:05:57 Task 4 is running on thread pool-1-thread-5
11:05:57 Task 0 is running on thread pool-1-thread-1
11:05:57 Task 1 is running on thread pool-1-thread-2
11:05:59 Task 6 is running on thread pool-1-thread-4
11:05:59 Task 5 is running on thread pool-1-thread-3
11:05:59 Task 7 is running on thread pool-1-thread-5
11:05:59 Task 8 is running on thread pool-1-thread-1
11:05:59 Task 9 is running on thread pool-1-thread-2
/**
* 创建只有一个线程的线程池,
* 因此本例中提交了10个任务,只能由这一个线程来逐个处理
*/
public class SingleThreadExecutorExample {
public static void main(String[] args) {
// 只有一个线程的线程池
ExecutorService executor = Executors.newSingleThreadExecutor();
// 提交任务给线程池
for (int i = 0; i < 10; i++) {
executor.submit(new SingleThreadExecutorExample.Task(i));
}
// 关闭线程池
executor.shutdown();
}
static class Task implements Runnable {
private int taskId;
public Task(int taskId) {
this.taskId = taskId;
}
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("hh:mm:ss")) + " Task " + taskId + " is running on thread " + Thread.currentThread().getName());
}
}
}
11:08:34 Task 0 is running on thread pool-1-thread-1
11:08:37 Task 1 is running on thread pool-1-thread-1
11:08:39 Task 2 is running on thread pool-1-thread-1
11:08:41 Task 3 is running on thread pool-1-thread-1
11:08:43 Task 4 is running on thread pool-1-thread-1
11:08:45 Task 5 is running on thread pool-1-thread-1
11:08:47 Task 6 is running on thread pool-1-thread-1
11:08:49 Task 7 is running on thread pool-1-thread-1
11:08:51 Task 8 is running on thread pool-1-thread-1
11:08:53 Task 9 is running on thread pool-1-thread-1
/**
* newCachedThreadPool()创建一个根据提交任务数量,动态调整线程数量的线程池
* 通过输出结果发现10个任务在同一时间被处理
*/
public class CachedThreadPoolExample {
public static void main(String[] args) {
// 创建一个根据任务数量动态调整的线程池
ExecutorService executor = Executors.newCachedThreadPool();
// 提交任务给线程池
for (int i = 0; i < 10; i++) {
executor.submit(new CachedThreadPoolExample.Task(i));
}
// 关闭线程池
executor.shutdown();
}
static class Task implements Runnable {
private int taskId;
public Task(int taskId) {
this.taskId = taskId;
}
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("hh:mm:ss")) + " Task " + taskId + " is running on thread " + Thread.currentThread().getName());
}
}
}
11:16:15 Task 3 is running on thread pool-1-thread-4
11:16:15 Task 5 is running on thread pool-1-thread-6
11:16:15 Task 8 is running on thread pool-1-thread-9
11:16:15 Task 9 is running on thread pool-1-thread-10
11:16:15 Task 2 is running on thread pool-1-thread-3
11:16:15 Task 6 is running on thread pool-1-thread-7
11:16:15 Task 4 is running on thread pool-1-thread-5
11:16:15 Task 0 is running on thread pool-1-thread-1
11:16:15 Task 7 is running on thread pool-1-thread-8
11:16:15 Task 1 is running on thread pool-1-thread-2
/**
* newScheduledThreadPool()创建延迟处理任务的线程池,可以设置核心线程数,本例中为3
* 调用schedule可以指定延迟处理的时间,处理任务的周期
*/
public class ScheduledThreadPoolExample {
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
// 延迟1秒后执行任务
executor.schedule(new Task("Task 1"), 1, TimeUnit.SECONDS);
// 每隔2秒执行一次任务
executor.scheduleAtFixedRate(new Task("Task 2"), 0, 2, TimeUnit.SECONDS);
// 延迟3秒后开始执行,然后每隔5秒执行一次任务
executor.scheduleWithFixedDelay(new Task("Task 3"), 3, 5, TimeUnit.SECONDS);
}
static class Task implements Runnable {
private String taskName;
public Task(String taskName) {
this.taskName = taskName;
}
@Override
public void run() {
System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("hh:mm:ss")) + " " + taskName + " is running on thread " + Thread.currentThread().getName());
}
}
}
本例输出结果为持续输出,这里只截取一部分输出结果
11:25:23 Task 2 is running on thread pool-1-thread-1
11:25:24 Task 1 is running on thread pool-1-thread-2
11:25:25 Task 2 is running on thread pool-1-thread-3
11:25:26 Task 3 is running on thread pool-1-thread-1
11:25:27 Task 2 is running on thread pool-1-thread-2
11:25:29 Task 2 is running on thread pool-1-thread-2
11:25:31 Task 2 is running on thread pool-1-thread-3
11:25:31 Task 3 is running on thread pool-1-thread-2
11:25:33 Task 2 is running on thread pool-1-thread-3
11:25:35 Task 2 is running on thread pool-1-thread-3
11:25:36 Task 3 is running on thread pool-1-thread-1