Java 线程池示例

一、任务类 HapdayTask4_Thread:

 1 package com.javabase.V18.concurrent.pool;
 2 
 3 import java.util.Calendar;
 4 import java.util.Random;
 5 import java.util.concurrent.Callable;
 6 
 7 /**
 8  * <p>任务是由线程承载的,具体来说是由线程类的具体方法来体现的,实际上这里的任务就是线程;<p/>
 9  * <p>线程本身就是一个对象,与普通对象最大的不同是可以运行,属于指令类数据。</p>
10  * <p>POJO 纯粹属于只承载参数的数据,POJO 可以翻译为朴素的、简单的 Java 对象。</p>
11  * <p>数据主要分为两类:一类是参数型数据;另一类是指令型数据。它们的关系是根据指令型数据操作参数型数据以完成特定的业务逻辑,即外在表现为实现某种功能。</p>
12  */
13 public class HapdayTask4_Thread implements Callable<String> {
14 
15     private int number;
16     private long sleepTime;
17 
18     public HapdayTask4_Thread(int number, long sleepTime) {
19         this.number = number;
20         this.sleepTime = sleepTime;
21     }
22 
23     @Override
24     public String toString() {
25         return "Hapday_Thread{number=" + number + '}';
26     }
27 
28     private long processCommand () {
29         try {
30             Thread.sleep(this.sleepTime);     // 模拟执行任务的用时
31         } catch (InterruptedException e) {
32             System.out.println("\033[33;1m 第 " + this.number + " 个线程被终止! \033[0m");
33 
34             e.printStackTrace();
35         }
36 
37         return sleepTime;
38     }
39 
40     private String getCurrentTime () {
41         Calendar calendar = Calendar.getInstance();
42 
43         String currentTime = calendar.get(Calendar.YEAR)
44                 + "-".concat( String.valueOf( 10 < (calendar.get(Calendar.MONDAY) + 1) ? (calendar.get(Calendar.MONDAY) + 1) : "0" + (calendar.get(Calendar.MONDAY) + 1) ) )
45                 + "-".concat ( 10 < calendar.get(Calendar.DAY_OF_MONTH) ? String.valueOf(calendar.get(Calendar.DAY_OF_MONTH)) : "0" + calendar.get(Calendar.DAY_OF_MONTH) )
46                 + " " + ( 10 < calendar.get(Calendar.HOUR) ? calendar.get(Calendar.HOUR) : "0" + calendar.get(Calendar.HOUR) )
47                 + ":" + ( 10 < calendar.get(Calendar.MINUTE) ? calendar.get(Calendar.MINUTE) : "0" + calendar.get(Calendar.MINUTE) )
48                 + ":" + ( 10 < calendar.get(Calendar.SECOND) ? calendar.get(Calendar.SECOND) : "0" + calendar.get(Calendar.SECOND) )
49                 + "." + calendar.get(Calendar.MILLISECOND);
50 
51         return currentTime;
52     }
53 
54     @Override
55     public String call() throws Exception {
56         String currentThreadName = Thread.currentThread().getName();
57         System.out.println("\033[35;2m".concat("时间 ").concat(this.getCurrentTime()).concat(" 开始执行第 ") + this.number + " 个任务 ".concat(currentThreadName).concat( "\033[0m"));
58         long duration = this.processCommand();  // 用时
59         System.out.println("\033[34;3m".concat("时间 ").concat(this.getCurrentTime()).concat(" 结束执行第 ") + this.number + " 个任务 ".concat(currentThreadName).concat(" 用时 " + duration + " 毫秒").concat( "\033[0m"));
60 
61         String result = "线程 ".concat(currentThreadName).concat(" 执行成功,用时 ").concat(duration + " 毫秒");
62         return result;
63     }
64 }

 

 

2、线程池测试类 ThreadPoolExecutor11_Test:

  1 package com.javabase.V18.concurrent.pool;
  2 
  3 import java.util.ArrayList;
  4 import java.util.List;
  5 import java.util.concurrent.*;
  6 
  7 public class ThreadPoolExecutor11_Test {
  8 
  9     private static final int CORE_THREAD_QUANTITY = 8;  // 核心线程数
 10     private static final int MAX_THREAD_QUANTITY = 16;  // 最大线程数
 11     private static final int TASK_QUEUE_CAPACITY = 100;  // 任务队列容量
 12     private static final long KEEP_ALIVE_TIME = 10;  // 存活时间
 13 
 14     /**
 15      * 这个主(main)方法也是一个线程,其建立与虚拟机的联系经过了很多步骤;
 16      * 主线程采用套接字接口通过 TCP 协议建立与虚拟机的联系。
 17      * @param args
 18      */
 19     public static void main(String[] args) {
 20 
 21         long beginTime = System.currentTimeMillis();
 22         System.out.println("\033[34;1m 开始时间 = " + beginTime + "\033[0m");
 23 
 24         ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(CORE_THREAD_QUANTITY
 25                 , MAX_THREAD_QUANTITY
 26                 , KEEP_ALIVE_TIME
 27                 , TimeUnit.SECONDS
 28                 , new ArrayBlockingQueue<>(TASK_QUEUE_CAPACITY)
 29                 , new ThreadPoolExecutor.CallerRunsPolicy()
 30         );      // 实例化线程池执行器类
 31 
 32         System.out.println("多线程执行任务 - 开始");
 33         int taskQuantity = 500;  // 任务数,当任务数超过了任务队列的容量后会创建非核心线程,否则完全由核心线程消化掉这些线程
 34         long duration = taskQuantity;
 35         List<Future<String>> hapday_future_list = new ArrayList<>();
 36         for ( int index = 0; index < taskQuantity; index++) {
 37             duration -= 1; // 休眠时长每次递减 1 毫秒
 38 
 39             Callable<String> hapdayTask = new HapdayTask4_Thread(index + 1, duration);    // 创建任务
 40             Future<String> hapday_future = threadPoolExecutor.submit(hapdayTask);     // 提交任务,这是个异步方法,会调用“执行(execute)”方法
 41             System.out.println("\033[33;1m threadPoolMonitor = " + threadPoolExecutor + "\033[0m");
 42 
 43             hapday_future_list.add(hapday_future);
 44         }
 45         System.out.println("多线程执行任务 - 结束");
 46 
 47         for ( Future hapday_future : hapday_future_list) {
 48             try {
 49                 System.out.println("\033[36;1m" + "执行结果:" + hapday_future.get() + "\033[0m");  // “获取(get)”方法会阻塞后续线程的执行,直到当前线程执行完毕才会进入执行
 50             } catch (InterruptedException e) {
 51                 e.printStackTrace();
 52             } catch (ExecutionException e) {
 53                 e.printStackTrace();
 54             }
 55         }
 56         System.out.println("\033[33;1m 0 秒后 threadPoolMonitor = " + threadPoolExecutor + "\033[0m");
 57 
 58         long endTime = System.currentTimeMillis();
 59         long sumTime = endTime - beginTime;
 60         System.out.println("\033[34;1m 用时 " + sumTime + " 毫秒 = " + sumTime / 1000 + " 秒 \033[0m");
 61 
 62         long delay = KEEP_ALIVE_TIME * 1000 - 1000;     // 延时 9 秒中,未超过“存活时长”
 63         try {
 64             Thread.sleep(delay);
 65         } catch (InterruptedException e) {
 66             e.printStackTrace();
 67         }
 68         System.out.println("\033[33;1m " + delay / 1000 + " 秒后 threadPoolMonitor = " + threadPoolExecutor + "\033[0m");
 69 
 70         delay = KEEP_ALIVE_TIME * 1000 + 1000;      // 延时 11 秒中,已超过“存活时长”,“非核心线程”被回收,如有新超过队列容量的任务过来后再创建
 71         try {
 72             Thread.sleep(delay);
 73         } catch (InterruptedException e) {
 74             e.printStackTrace();
 75         }
 76         System.out.println("\033[33;1m " + delay / 1000 + " 秒后 threadPoolMonitor = " + threadPoolExecutor + "\033[0m");
 77 
 78         delay = 5000;      // 修整 5 秒以便观察
 79         try {
 80             Thread.sleep(delay);
 81         } catch (InterruptedException e) {
 82             e.printStackTrace();
 83         }
 84         System.out.println("\033[33;1m " + delay / 1000 + " 秒后 threadPoolMonitor = " + threadPoolExecutor + "\033[0m");
 85 
 86         System.out.println("再来一拨任务 - 开始");
 87         taskQuantity = 500;  // 任务数,当任务数超过了任务队列的容量后会创建非核心线程,否则完全由核心线程消化掉这些线程
 88         duration = taskQuantity;
 89         System.out.println("\033[33;1m 清空前 = " + hapday_future_list.size() + "\033[0m");
 90         hapday_future_list.clear();     // 清空
 91         System.out.println("\033[33;1m 清空后 = " + hapday_future_list.size() + "\033[0m");
 92         for ( int index = 0; index < taskQuantity; index++) {
 93             duration -= 1; // 休眠时长每次递减 1 毫秒
 94 
 95             Callable<String> hapdayTask = new HapdayTask4_Thread(index + 1, duration);    // 创建任务
 96             Future<String> hapday_future = threadPoolExecutor.submit(hapdayTask);     // 提交任务,这是个异步方法,会调用“执行(execute)”方法
 97             System.out.println("\033[33;1m threadPoolMonitor = " + threadPoolExecutor + "\033[0m");
 98 
 99             hapday_future_list.add(hapday_future);
100         }
101         System.out.println("再来一拨任务 - 结束");
102 
103         for ( Future hapday_future : hapday_future_list) {
104             try {
105                 System.out.println("\033[36;1m" + "执行结果:" + hapday_future.get() + "\033[0m");  // “获取(get)”方法会阻塞后续线程的执行,直到当前线程执行完毕才会进入执行
106             } catch (InterruptedException e) {
107                 e.printStackTrace();
108             } catch (ExecutionException e) {
109                 e.printStackTrace();
110             }
111         }
112         System.out.println("\033[33;1m 0 秒后 threadPoolMonitor = " + threadPoolExecutor + "\033[0m");
113 
114         endTime = System.currentTimeMillis();
115         sumTime = endTime - beginTime;
116         System.out.println("\033[34;1m 用时 " + sumTime + " 毫秒 = " + sumTime / 1000 + " 秒 \033[0m");
117 
118         delay = KEEP_ALIVE_TIME * 1000 - 1000;     // 延时 9 秒中,未超过“存活时长”
119         try {
120             Thread.sleep(delay);
121         } catch (InterruptedException e) {
122             e.printStackTrace();
123         }
124         System.out.println("\033[33;1m " + delay / 1000 + " 秒后 threadPoolMonitor = " + threadPoolExecutor + "\033[0m");
125 
126         delay = KEEP_ALIVE_TIME * 1000 + 1000;      // 延时 11 秒中,已超过“存活时长”,“非核心线程”被回收,如有新超过队列容量的任务过来后再创建
127         try {
128             Thread.sleep(delay);
129         } catch (InterruptedException e) {
130             e.printStackTrace();
131         }
132         System.out.println("\033[33;1m " + delay / 1000 + " 秒后 threadPoolMonitor = " + threadPoolExecutor + "\033[0m");
133 
134         delay = 5000;      // 修整 5 秒以便观察
135         try {
136             Thread.sleep(delay);
137         } catch (InterruptedException e) {
138             e.printStackTrace();
139         }
140         System.out.println("\033[33;1m " + delay / 1000 + " 秒后 threadPoolMonitor = " + threadPoolExecutor + "\033[0m");
141 
142         threadPoolExecutor.shutdown();  // 关闭线程池
143 
144     }
145 
146 }

 

 

 


posted @ 2022-08-09 21:18  hapday  阅读(861)  评论(0编辑  收藏  举报