JUC-09-线程池

JUC-09-线程池

1. 池化技术

  • 线程池
  • 内存池
  • 连接池
  • 对象池

以上池化技术都是优化系统资源

池化技术:事先准备好一些资源,有人要用,就来我这里拿,用来之后还给我。

线程池的好处:

  • 降低系统的消耗
  • 方便管理
  • 可以复用,控制最大并发数

线程池:三大方法,七大参数,四种拒绝策略

2. 三大方法

  • 三大方法简单使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Executors 工具类 :三大方法
// 使用线程池之后是使用线程池来创建线程

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class demo01 {
public static void main(String[] args) {
// ExecutorService threadPool = Executors.newSingleThreadExecutor();// 单个线程
// ExecutorService threadPool = Executors.newCachedThreadPool();// 可伸缩的
ExecutorService threadPool = Executors.newFixedThreadPool(5);// 创建一个固定的线程池


try {
for (int i = 0; i < 10; i++) {
// 使用了线程池之后,使用线程池来创建对象
threadPool.execute(()->{
System.out.println(Thread.currentThread().getName()+"线程");
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 线程池用完,程序结束,关闭线程池
threadPool.shutdown();
}
}
}

3. 七大参数

  • 底层源码分析:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
    public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}

public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}

public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}

// 本质:以上方法开启了ThreadPoolExecutor
// 七大参数:
public ThreadPoolExecutor(int corePoolSize, // 核心线程池大小
int maximumPoolSize, // 最大线程池大小
long keepAliveTime, // 超时了没有人用就会释放
TimeUnit unit, // 超时单位
BlockingQueue<Runnable> workQueue, // 阻塞队列
ThreadFactory threadFactory, // 线程工厂
RejectedExecutionHandler handler // 拒绝策略
) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}

在阿里巴巴开发手册中有这样一段描述:

mark

7大参数形象比喻:

mark

3. 四种拒绝策略

mark

自定义线程池:

  1. abortPolicy:抛出异常
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class demo02 {
public static void main(String[] args) {
// 自定义线程池
ThreadPoolExecutor threadPool_1 = new ThreadPoolExecutor(
2,
5,
3,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy() // 银行满了,但是还有人进来,就不处理这个人的,抛出异常
);


try {
// 最大承载:deque + max
// 超出最大承载抛出异常:java.util.concurrent.RejectedExecutionException
for (int i = 1; i <= 9; i++) {
// 使用了线程池之后,使用线程池来创建对象
threadPool_1.execute(()->{
System.out.println(Thread.currentThread().getName()+"线程");
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 线程池用完,程序结束,关闭线程池
threadPool_1.shutdown();
}
}
}
  1. CallerRunsPolicy()
1
new ThreadPoolExecutor.CallerRunsPolicy() // 哪里来的去哪里:打发走
1
2
3
4
5
6
7
8
9
main线程 // main线程去执行
pool-1-thread-2线程
pool-1-thread-2线程
pool-1-thread-2线程
pool-1-thread-2线程
pool-1-thread-1线程
pool-1-thread-3线程
pool-1-thread-5线程
pool-1-thread-4线程
  1. DiscardPolicy()
1
new ThreadPoolExecutor.DiscardPolicy() // 队列满了,丢掉任务不会抛出异常
  1. DiscardOldestPolicy()
1
new ThreadPoolExecutor.DiscardOldestPolicy() // 队列满了,尝试和最早的线程竞争,竞争失败就还是抛弃任务

5. 小结

最大线程池到底该如何定义?

  • CPU 密集型 : 几核CPU就是几条线程,保持CPU效率最高
  • IO 密集型 : 判断程序中十分耗IO的线程有多少个,只要大于这个数就可以
1
2
   // 获取CPU的核心数
System.out.println(Runtime.getRuntime().availableProcessors());s
打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2019-2022 Zhuuu
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信