?系统启动一个新线程的成本时比较高的,因为它涉及于操作系统交涉。在这种情形下,使用线程池可以很好地提高性能,尤其是当程序中需要创建大量生存期限很短的线程时,更应该考虑使用线程池。
?与数据库连接池类似的是,线程池在启动时即创建大量空闲的线程,程序将一个Runnable对像或Callable对象传给线程池,线程池就会启动一个线程来执行他们的run()或call()方法,放run()或call()方法执行结束后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个Runnable对象的run()或call()方法。
?除此之外,使用线程池可以有效地控制系统中并发线程的数量,当系统中包含大量并发线程时,会导致系统性能急剧下降,甚至导致JVM崩溃,而线程池的最大线程数参数可以控制系统中并发线程数不超过此数。
?在Java5以前,开发者必须手动实现自己的线程池;从Java5开始,Java内建支持线程池。Java5新增了一个Executors工厂类来产生线程池,该工厂类包含了如下几个静态工厂方法来创建线程池。
?上面7个方法中前三个方法返回ExecutorService对象,该对象代表一个线程池,它可以执行Runnable对象或Callable对象所代表的线程;而中间两个方法返回一个ScheduledExecutorSerivce线程池,它是ExecutorService的子类,它可以在指定延迟后执行线程任务;最后两个方法则是Java8新增的,这两个方法可以充分利用多CPU并行能力。这两个方法生成的work stealing池,都相当于后台线程池,如果所有的前台线程都死亡了,work stealing 池中的线程会自动死亡。
?由于目前计算机硬件的发展日新月异,即使普通用户的电脑通常也都是多核CPU,因此Java8在线程支持上也增加了利用多CPU并行的能力,这样可以更好地发挥底层硬件的性能。
?ExecutorService代表尽快执行线程的线程池(只要线程池中有空闲线程,就立即执行线程任务),程序只要将一个Runnable对象或Callable对象(代表线程任务)提交给该线程池,该线程池会尽快执行该任务。ExecutorService里提供了如下三个方法。
?ScheduledExecutorService代表可在指定延迟后或周期性地执行线程任务的线程池,它提供如下4个方法。
?用完一个线程池后,应该调用该线程池的shutdown()方法,该方法将启动线程池的关闭序列,调用shutdown()方法后的线程池不再接受新任务,但会将以前所有已提交任务执行完成。当线程池中所有任务执行完成后,池中的所有线程都会死亡;另外也可以调用线程池的shutdownNow()方法来关闭线程池,改方法试图停止所有正在执行的活动任务,暂停处理正在等待的任务,并返回等待执行的任务列表。
使用线程池来执行线程任务的步骤如下:
示例代码:
public class ThreadPoolTest {
public static void main(String[] args) {
//创建一个具有固定线程数的线程池
ExecutorService executorService = Executors.newFixedThreadPool(6);
Runnable target = () -> {
for (int i = 0; i < 10; i++) {
System.out.println("t_name:" + Thread.currentThread().getName() + ",i:" + i);
}
};
//向线程池中提交两个线程
executorService.submit(target);
executorService.submit(target);
//关闭线程池
executorService.shutdown();
}
}
运行结果:
t_name:pool-1-thread-1,i:0
t_name:pool-1-thread-1,i:1
t_name:pool-1-thread-1,i:2
t_name:pool-1-thread-1,i:3
t_name:pool-1-thread-1,i:4
t_name:pool-1-thread-2,i:0
t_name:pool-1-thread-1,i:5
t_name:pool-1-thread-1,i:6
t_name:pool-1-thread-2,i:1
t_name:pool-1-thread-1,i:7
t_name:pool-1-thread-1,i:8
t_name:pool-1-thread-2,i:2
t_name:pool-1-thread-1,i:9
t_name:pool-1-thread-2,i:3
t_name:pool-1-thread-2,i:4
t_name:pool-1-thread-2,i:5
t_name:pool-1-thread-2,i:6
t_name:pool-1-thread-2,i:7
t_name:pool-1-thread-2,i:8
t_name:pool-1-thread-2,i:9
注意:创建了Runnable实现类之后程序没有直接创建线程,启动线程来执行该Runnable任务,而是通过线程池来执行该任务。
?为了充分利用CPU,多核CPU的性能优势,计算机软件系统可以充分“挖掘”每个CPU的计算能力,绝不能让某个CPU处于“空闲”状态。为了充分利用多CPU,多核CPU的优势,可以考虑把一个任务拆分成多个“小任务”,把多个“小任务”放在多个处理器核心上并行执行;当多个“小任务”执行完成之后,再将这些执行结果合并起来即可。
?Java7提供了ForkJoinPool来支持将一个任务拆分成多个“小任务”并行计算,再把多个“小任务”的结果合并成总的计算结果。ForkJoinPool是ExecutorService的实现类,因此是一种特殊的线程池。ForkJoinPool提供了如下两个常用的构造器。
?Java8进一步扩展了ForkJoinPool的功能,Java8为ForkJoinPool增加了通用池功能。ForkJoinPool类通过如下两个静态方法提供通用池功能。
?创建了ForkJoinPool实例后,就可以调用ForkJoinPool的submit(ForkJoinTask task)或invoke(ForkJoinTask task)方法来执行指定任务了,其中ForkJoinTask代表一个可以并行,合并的任务。ForkJoinTask 是一个抽象类,它还有两个抽象子类:RecursiveAction和RecursiveTask。其中RecursiveTask代表有返回值的任务,而RecursiveAction代表没有返回值的任务。

?下面以执行没有返回值的“大任务”(简单地打印0-300的数值)为例,程序将一个“大任务”拆分成多个“小任务”,并将任务交给ForkJoinPool来执行:
public class PrintTask extends RecursiveAction {
//每个“小任务最多打印50个数”
private static final int THRESHOLD = 50;
private int start;
private int end;
public PrintTask(int start, int end) {
this.start = start;
this.end = end;
}
@Override
protected void compute() {
if (end - start < THRESHOLD) {
for (int i = start; i < end; i++) {
System.out.println(Thread.currentThread().getName() + "的i值:" + i);
}
} else {
//当end与start之间的差值大于THRESHOLD,即要打印的数超过50个时
//将大任务分解成两个“小任务”
int middle = (start + end) / 2;
PrintTask left = new PrintTask(start, middle);
PrintTask right = new PrintTask(middle, end);
//并行执行两个“小任务”
left.fork();
right.fork();
}
}
}
public class ForkJoinPoolTest {
public static void main(String[] args) throws InterruptedException {
ForkJoinPool pool = new ForkJoinPool();
//提交可分解的PrintTask任务
pool.submit(new PrintTask(1, 300));
pool.awaitTermination(2, TimeUnit.SECONDS);
//关闭线程池
pool.shutdown();
}
}
运行结果:
ForkJoinPool-1-worker-2的i值:112
ForkJoinPool-1-worker-2的i值:113
ForkJoinPool-1-worker-2的i值:114
ForkJoinPool-1-worker-4的i值:38
ForkJoinPool-1-worker-6的i值:150
ForkJoinPool-1-worker-1的i值:262
ForkJoinPool-1-worker-3的i值:187
ForkJoinPool-1-worker-1的i值:263
ForkJoinPool-1-worker-6的i值:151
ForkJoinPool-1-worker-6的i值:152
ForkJoinPool-1-worker-4的i值:39
ForkJoinPool-1-worker-2的i值:115
ForkJoinPool-1-worker-4的i值:40
ForkJoinPool-1-worker-6的i值:153
ForkJoinPool-1-worker-0的i值:1
ForkJoinPool-1-worker-5的i值:75
ForkJoinPool-1-worker-1的i值:264
ForkJoinPool-1-worker-7的i值:225
ForkJoinPool-1-worker-3的i值:188
ForkJoinPool-1-worker-7的i值:226
ForkJoinPool-1-worker-1的i值:265
ForkJoinPool-1-worker-5的i值:76
ForkJoinPool-1-worker-0的i值:2
ForkJoinPool-1-worker-0的i值:3
ForkJoinPool-1-worker-6的i值:154
ForkJoinPool-1-worker-4的i值:41
ForkJoinPool-1-worker-2的i值:116
ForkJoinPool-1-worker-2的i值:117
ForkJoinPool-1-worker-2的i值:118
ForkJoinPool-1-worker-2的i值:119
ForkJoinPool-1-worker-2的i值:120
ForkJoinPool-1-worker-2的i值:121
ForkJoinPool-1-worker-4的i值:42
ForkJoinPool-1-worker-6的i值:155
ForkJoinPool-1-worker-0的i值:4
ForkJoinPool-1-worker-0的i值:5
ForkJoinPool-1-worker-0的i值:6
ForkJoinPool-1-worker-5的i值:77
ForkJoinPool-1-worker-1的i值:266
ForkJoinPool-1-worker-7的i值:227
ForkJoinPool-1-worker-3的i值:189
ForkJoinPool-1-worker-3的i值:190
ForkJoinPool-1-worker-3的i值:191
ForkJoinPool-1-worker-7的i值:228
ForkJoinPool-1-worker-1的i值:267
ForkJoinPool-1-worker-5的i值:78
ForkJoinPool-1-worker-0的i值:7
ForkJoinPool-1-worker-0的i值:8
ForkJoinPool-1-worker-6的i值:156
ForkJoinPool-1-worker-4的i值:43
ForkJoinPool-1-worker-2的i值:122
ForkJoinPool-1-worker-4的i值:44
ForkJoinPool-1-worker-6的i值:157
ForkJoinPool-1-worker-0的i值:9
ForkJoinPool-1-worker-5的i值:79
ForkJoinPool-1-worker-1的i值:268
ForkJoinPool-1-worker-7的i值:229
ForkJoinPool-1-worker-3的i值:192
ForkJoinPool-1-worker-7的i值:230
ForkJoinPool-1-worker-1的i值:269
ForkJoinPool-1-worker-5的i值:80
ForkJoinPool-1-worker-1的i值:270
ForkJoinPool-1-worker-0的i值:10
ForkJoinPool-1-worker-6的i值:158
ForkJoinPool-1-worker-4的i值:45
ForkJoinPool-1-worker-4的i值:46
ForkJoinPool-1-worker-4的i值:47
ForkJoinPool-1-worker-2的i值:123
ForkJoinPool-1-worker-4的i值:48
ForkJoinPool-1-worker-6的i值:159
ForkJoinPool-1-worker-0的i值:11
ForkJoinPool-1-worker-1的i值:271
ForkJoinPool-1-worker-5的i值:81
ForkJoinPool-1-worker-7的i值:231
ForkJoinPool-1-worker-3的i值:193
ForkJoinPool-1-worker-7的i值:232
ForkJoinPool-1-worker-5的i值:82
ForkJoinPool-1-worker-1的i值:272
ForkJoinPool-1-worker-0的i值:12
ForkJoinPool-1-worker-6的i值:160
ForkJoinPool-1-worker-4的i值:49
ForkJoinPool-1-worker-2的i值:124
ForkJoinPool-1-worker-4的i值:50
ForkJoinPool-1-worker-6的i值:161
ForkJoinPool-1-worker-0的i值:13
ForkJoinPool-1-worker-1的i值:273
ForkJoinPool-1-worker-5的i值:83
ForkJoinPool-1-worker-7的i值:233
ForkJoinPool-1-worker-7的i值:234
ForkJoinPool-1-worker-7的i值:235
ForkJoinPool-1-worker-7的i值:236
ForkJoinPool-1-worker-7的i值:237
ForkJoinPool-1-worker-7的i值:238
ForkJoinPool-1-worker-7的i值:239
ForkJoinPool-1-worker-7的i值:240
ForkJoinPool-1-worker-7的i值:241
ForkJoinPool-1-worker-3的i值:194
ForkJoinPool-1-worker-7的i值:242
ForkJoinPool-1-worker-7的i值:243
ForkJoinPool-1-worker-7的i值:244
ForkJoinPool-1-worker-7的i值:245
ForkJoinPool-1-worker-7的i值:246
ForkJoinPool-1-worker-7的i值:247
ForkJoinPool-1-worker-5的i值:84
ForkJoinPool-1-worker-1的i值:274
ForkJoinPool-1-worker-0的i值:14
ForkJoinPool-1-worker-6的i值:162
ForkJoinPool-1-worker-4的i值:51
ForkJoinPool-1-worker-2的i值:125
ForkJoinPool-1-worker-2的i值:126
ForkJoinPool-1-worker-2的i值:127
ForkJoinPool-1-worker-2的i值:128
ForkJoinPool-1-worker-2的i值:129
ForkJoinPool-1-worker-4的i值:52
ForkJoinPool-1-worker-6的i值:163
ForkJoinPool-1-worker-6的i值:164
ForkJoinPool-1-worker-6的i值:165
ForkJoinPool-1-worker-6的i值:166
ForkJoinPool-1-worker-6的i值:167
ForkJoinPool-1-worker-6的i值:168
ForkJoinPool-1-worker-0的i值:15
ForkJoinPool-1-worker-1的i值:275
ForkJoinPool-1-worker-5的i值:85
ForkJoinPool-1-worker-7的i值:248
ForkJoinPool-1-worker-7的i值:249
ForkJoinPool-1-worker-7的i值:250
ForkJoinPool-1-worker-7的i值:251
ForkJoinPool-1-worker-7的i值:252
ForkJoinPool-1-worker-3的i值:195
ForkJoinPool-1-worker-7的i值:253
ForkJoinPool-1-worker-5的i值:86
ForkJoinPool-1-worker-1的i值:276
ForkJoinPool-1-worker-0的i值:16
ForkJoinPool-1-worker-6的i值:169
ForkJoinPool-1-worker-4的i值:53
ForkJoinPool-1-worker-2的i值:130
ForkJoinPool-1-worker-4的i值:54
ForkJoinPool-1-worker-6的i值:170
ForkJoinPool-1-worker-0的i值:17
ForkJoinPool-1-worker-1的i值:277
ForkJoinPool-1-worker-5的i值:87
ForkJoinPool-1-worker-7的i值:254
ForkJoinPool-1-worker-3的i值:196
ForkJoinPool-1-worker-7的i值:255
ForkJoinPool-1-worker-5的i值:88
ForkJoinPool-1-worker-1的i值:278
ForkJoinPool-1-worker-0的i值:18
ForkJoinPool-1-worker-6的i值:171
ForkJoinPool-1-worker-4的i值:55
ForkJoinPool-1-worker-2的i值:131
ForkJoinPool-1-worker-4的i值:56
ForkJoinPool-1-worker-6的i值:172
ForkJoinPool-1-worker-0的i值:19
ForkJoinPool-1-worker-1的i值:279
ForkJoinPool-1-worker-5的i值:89
ForkJoinPool-1-worker-7的i值:256
ForkJoinPool-1-worker-7的i值:257
ForkJoinPool-1-worker-7的i值:258
ForkJoinPool-1-worker-7的i值:259
ForkJoinPool-1-worker-7的i值:260
ForkJoinPool-1-worker-7的i值:261
ForkJoinPool-1-worker-3的i值:197
ForkJoinPool-1-worker-5的i值:90
ForkJoinPool-1-worker-1的i值:280
ForkJoinPool-1-worker-1的i值:281
ForkJoinPool-1-worker-0的i值:20
ForkJoinPool-1-worker-0的i值:21
ForkJoinPool-1-worker-0的i值:22
ForkJoinPool-1-worker-0的i值:23
ForkJoinPool-1-worker-0的i值:24
ForkJoinPool-1-worker-0的i值:25
ForkJoinPool-1-worker-0的i值:26
ForkJoinPool-1-worker-0的i值:27
ForkJoinPool-1-worker-0的i值:28
ForkJoinPool-1-worker-0的i值:29
ForkJoinPool-1-worker-0的i值:30
ForkJoinPool-1-worker-6的i值:173
ForkJoinPool-1-worker-4的i值:57
ForkJoinPool-1-worker-2的i值:132
ForkJoinPool-1-worker-2的i值:133
ForkJoinPool-1-worker-2的i值:134
ForkJoinPool-1-worker-2的i值:135
ForkJoinPool-1-worker-2的i值:136
ForkJoinPool-1-worker-2的i值:137
ForkJoinPool-1-worker-2的i值:138
ForkJoinPool-1-worker-2的i值:139
ForkJoinPool-1-worker-2的i值:140
ForkJoinPool-1-worker-4的i值:58
ForkJoinPool-1-worker-6的i值:174
ForkJoinPool-1-worker-0的i值:31
ForkJoinPool-1-worker-0的i值:32
ForkJoinPool-1-worker-0的i值:33
ForkJoinPool-1-worker-1的i值:282
ForkJoinPool-1-worker-1的i值:283
ForkJoinPool-1-worker-1的i值:284
ForkJoinPool-1-worker-1的i值:285
ForkJoinPool-1-worker-5的i值:91
ForkJoinPool-1-worker-3的i值:198
ForkJoinPool-1-worker-3的i值:199
ForkJoinPool-1-worker-3的i值:200
ForkJoinPool-1-worker-3的i值:201
ForkJoinPool-1-worker-3的i值:202
ForkJoinPool-1-worker-3的i值:203
ForkJoinPool-1-worker-3的i值:204
ForkJoinPool-1-worker-3的i值:205
ForkJoinPool-1-worker-3的i值:206
ForkJoinPool-1-worker-3的i值:207
ForkJoinPool-1-worker-3的i值:208
ForkJoinPool-1-worker-3的i值:209
ForkJoinPool-1-worker-3的i值:210
ForkJoinPool-1-worker-3的i值:211
ForkJoinPool-1-worker-5的i值:92
ForkJoinPool-1-worker-5的i值:93
ForkJoinPool-1-worker-1的i值:286
ForkJoinPool-1-worker-0的i值:34
ForkJoinPool-1-worker-6的i值:175
ForkJoinPool-1-worker-4的i值:59
ForkJoinPool-1-worker-2的i值:141
ForkJoinPool-1-worker-4的i值:60
ForkJoinPool-1-worker-6的i值:176
ForkJoinPool-1-worker-0的i值:35
ForkJoinPool-1-worker-1的i值:287
ForkJoinPool-1-worker-5的i值:94
ForkJoinPool-1-worker-5的i值:95
ForkJoinPool-1-worker-5的i值:96
ForkJoinPool-1-worker-5的i值:97
ForkJoinPool-1-worker-3的i值:212
ForkJoinPool-1-worker-5的i值:98
ForkJoinPool-1-worker-1的i值:288
ForkJoinPool-1-worker-1的i值:289
ForkJoinPool-1-worker-1的i值:290
ForkJoinPool-1-worker-1的i值:291
ForkJoinPool-1-worker-1的i值:292
ForkJoinPool-1-worker-1的i值:293
ForkJoinPool-1-worker-0的i值:36
ForkJoinPool-1-worker-6的i值:177
ForkJoinPool-1-worker-6的i值:178
ForkJoinPool-1-worker-6的i值:179
ForkJoinPool-1-worker-6的i值:180
ForkJoinPool-1-worker-6的i值:181
ForkJoinPool-1-worker-4的i值:61
ForkJoinPool-1-worker-2的i值:142
ForkJoinPool-1-worker-4的i值:62
ForkJoinPool-1-worker-6的i值:182
ForkJoinPool-1-worker-0的i值:37
ForkJoinPool-1-worker-1的i值:294
ForkJoinPool-1-worker-1的i值:295
ForkJoinPool-1-worker-1的i值:296
ForkJoinPool-1-worker-1的i值:297
ForkJoinPool-1-worker-1的i值:298
ForkJoinPool-1-worker-1的i值:299
ForkJoinPool-1-worker-5的i值:99
ForkJoinPool-1-worker-5的i值:100
ForkJoinPool-1-worker-5的i值:101
ForkJoinPool-1-worker-5的i值:102
ForkJoinPool-1-worker-5的i值:103
ForkJoinPool-1-worker-3的i值:213
ForkJoinPool-1-worker-3的i值:214
ForkJoinPool-1-worker-3的i值:215
ForkJoinPool-1-worker-3的i值:216
ForkJoinPool-1-worker-5的i值:104
ForkJoinPool-1-worker-6的i值:183
ForkJoinPool-1-worker-6的i值:184
ForkJoinPool-1-worker-6的i值:185
ForkJoinPool-1-worker-6的i值:186
ForkJoinPool-1-worker-4的i值:63
ForkJoinPool-1-worker-2的i值:143
ForkJoinPool-1-worker-2的i值:144
ForkJoinPool-1-worker-4的i值:64
ForkJoinPool-1-worker-5的i值:105
ForkJoinPool-1-worker-5的i值:106
ForkJoinPool-1-worker-5的i值:107
ForkJoinPool-1-worker-5的i值:108
ForkJoinPool-1-worker-3的i值:217
ForkJoinPool-1-worker-5的i值:109
ForkJoinPool-1-worker-5的i值:110
ForkJoinPool-1-worker-5的i值:111
ForkJoinPool-1-worker-4的i值:65
ForkJoinPool-1-worker-2的i值:145
ForkJoinPool-1-worker-2的i值:146
ForkJoinPool-1-worker-2的i值:147
ForkJoinPool-1-worker-2的i值:148
ForkJoinPool-1-worker-2的i值:149
ForkJoinPool-1-worker-4的i值:66
ForkJoinPool-1-worker-4的i值:67
ForkJoinPool-1-worker-3的i值:218
ForkJoinPool-1-worker-4的i值:68
ForkJoinPool-1-worker-3的i值:219
ForkJoinPool-1-worker-4的i值:69
ForkJoinPool-1-worker-3的i值:220
ForkJoinPool-1-worker-4的i值:70
ForkJoinPool-1-worker-3的i值:221
ForkJoinPool-1-worker-3的i值:222
ForkJoinPool-1-worker-3的i值:223
ForkJoinPool-1-worker-4的i值:71
ForkJoinPool-1-worker-3的i值:224
ForkJoinPool-1-worker-4的i值:72
ForkJoinPool-1-worker-4的i值:73
ForkJoinPool-1-worker-4的i值:74
?如果大任务时有返回值的任务,则可以让任务继承RecursiveTask<T>,其中泛型参数T就代表了改任务的返回值类型。代码示例省略。
文章内容均取自《疯狂Java讲义-李刚》一书中多线程章节。截取重要知识点作为笔记记录,方便自己回顾。
原文:https://www.cnblogs.com/everyingo/p/12824997.html