- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Java线程池大小的设置方法实例由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
首先我们要先知道 Java 中创建线程池的方式,java中创建线程池的方式一般有两种,如下所示:
上代码:
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
package
com.base.demo.design.play;
import
java.util.concurrent.ExecutorService;
import
java.util.concurrent.Executors;
import
java.util.concurrent.ScheduledExecutorService;
import
java.util.concurrent.TimeUnit;
/**
* @Description: 线程池代码
* @BelongsProject: base-demo-design
* @BelongsPackage: com.base.demo.design.play
* @Author: ChenYongJia
* @CreateTime: 2021-08-14 15:26
* @Email: chen87647213@163.com
* @Version: 1.0
*/
public
class
TestThreadPoolExecutor {
public
static
void
main(String[] args) {
// 创建使用单个线程的线程池
ExecutorService es1 = Executors.newSingleThreadExecutor();
for
(
int
i =
0
; i <
10
; i++) {
es1.submit(
new
Runnable() {
@Override
public
void
run() {
System.out.println(Thread.currentThread().getName() +
"正在执行任务"
);
}
});
}
// 创建使用固定线程数的线程池
ExecutorService es2 = Executors.newFixedThreadPool(
3
);
for
(
int
i =
0
; i <
10
; i++) {
es2.submit(
new
Runnable() {
@Override
public
void
run() {
System.out.println(Thread.currentThread().getName() +
"正在执行任务"
);
}
});
}
// 创建一个会根据需要创建新线程的线程池
ExecutorService es3 = Executors.newCachedThreadPool();
for
(
int
i =
0
; i <
20
; i++) {
es3.submit(
new
Runnable() {
@Override
public
void
run() {
System.out.println(Thread.currentThread().getName() +
"正在执行任务"
);
}
});
}
// 创建拥有固定线程数量的定时线程任务的线程池
ScheduledExecutorService es4 = Executors.newScheduledThreadPool(
2
);
System.out.println(
"时间:"
+ System.currentTimeMillis());
for
(
int
i =
0
; i <
5
; i++) {
es4.schedule(
new
Runnable() {
@Override
public
void
run() {
System.out.println(
"时间:"
+System.currentTimeMillis()+
"--"
+Thread.currentThread().getName() +
"正在执行任务"
);
}
},
3
, TimeUnit.SECONDS);
}
// 创建只有一个线程的定时线程任务的线程池
ScheduledExecutorService es5 = Executors.newSingleThreadScheduledExecutor();
System.out.println(
"时间:"
+ System.currentTimeMillis());
for
(
int
i =
0
; i <
5
; i++) {
es5.schedule(
new
Runnable() {
@Override
public
void
run() {
System.out.println(
"时间:"
+System.currentTimeMillis()+
"--"
+Thread.currentThread().getName() +
"正在执行任务"
);
}
},
3
, TimeUnit.SECONDS);
}
}
}
|
运行结果如下:
pool-1-thread-1正在执行任务 pool-1-thread-1正在执行任务 pool-1-thread-1正在执行任务 pool-1-thread-1正在执行任务 pool-1-thread-1正在执行任务 pool-1-thread-1正在执行任务 pool-1-thread-1正在执行任务 pool-1-thread-1正在执行任务 pool-1-thread-1正在执行任务 pool-1-thread-1正在执行任务 pool-2-thread-1正在执行任务 pool-2-thread-2正在执行任务 pool-2-thread-1正在执行任务 pool-2-thread-3正在执行任务 pool-2-thread-2正在执行任务 pool-2-thread-3正在执行任务 pool-2-thread-1正在执行任务 pool-2-thread-3正在执行任务 pool-2-thread-2正在执行任务 pool-2-thread-1正在执行任务 pool-3-thread-1正在执行任务 pool-3-thread-2正在执行任务 pool-3-thread-2正在执行任务 pool-3-thread-3正在执行任务 pool-3-thread-1正在执行任务 pool-3-thread-3正在执行任务 pool-3-thread-4正在执行任务 pool-3-thread-1正在执行任务 pool-3-thread-3正在执行任务 pool-3-thread-4正在执行任务 pool-3-thread-5正在执行任务 pool-3-thread-4正在执行任务 pool-3-thread-6正在执行任务 pool-3-thread-7正在执行任务 pool-3-thread-8正在执行任务 pool-3-thread-9正在执行任务 pool-3-thread-2正在执行任务 pool-3-thread-6正在执行任务 pool-3-thread-1正在执行任务 pool-3-thread-3正在执行任务 时间:1628926041159 时间:1628926041160 时间:1628926044172--pool-5-thread-1正在执行任务 时间:1628926044172--pool-4-thread-2正在执行任务 时间:1628926044172--pool-4-thread-1正在执行任务 时间:1628926044172--pool-4-thread-2正在执行任务 时间:1628926044172--pool-5-thread-1正在执行任务 时间:1628926044172--pool-4-thread-2正在执行任务 时间:1628926044172--pool-4-thread-1正在执行任务 时间:1628926044172--pool-5-thread-1正在执行任务 时间:1628926044172--pool-5-thread-1正在执行任务 时间:1628926044172--pool-5-thread-1正在执行任务 。
1
2
3
4
5
6
7
|
public
ThreadPoolExecutor(
int
corePoolSize,
//线程池的核心线程数量
int
maximumPoolSize,
//线程池的最大线程数
long
keepAliveTime,
//当线程数大于核心线程数时,多余的空闲线程存活的最长时间
TimeUnit unit,
//时间单位
BlockingQueue<Runnable> workQueue,
//任务队列,用来储存等待执行任务的队列
ThreadFactory threadFactory,
//线程工厂,用来创建线程,一般默认即可
RejectedExecutionHandler handler)
//拒绝策略,当提交的任务过多而不能及时处理时,我们可以定制策略来处理任务
|
1
2
3
4
5
6
7
|
TimeUnit.DAYS;
//天
TimeUnit.HOURS;
//小时
TimeUnit.MINUTES;
//分钟
TimeUnit.SECONDS;
//秒
TimeUnit.MILLISECONDS;
//毫秒
TimeUnit.MICROSECONDS;
//微妙
TimeUnit.NANOSECONDS;
//纳秒
|
AbortPolicy:默认的拒绝策略,直接抛出异常。`throws RejectedExecutionException`。 CallerRunsPolicy:只用调用者所在线程来运行任务(提交任务的线程自己去执行该任务)。 DiscardOldestPolicy:丢弃最老的任务,其实就是把最早进入工作队列的任务丢弃,然后把新任务加入到工作队列。 DiscardPolicy:不处理,直接丢弃任务,没有任何异常抛出.
执行流程:
一般多线程执行的任务类型可以分为 CPU 密集型 和 I/O 密集型,根据不同的任务类型,我们计算线程数的方法也不一样。创建多少线程合适,要看多线程具体的应用场景。我们的程序一般都是 CPU 计算 和 I/O 操作交叉执行 的,由于 I/O 设备 的速度相对于 CPU 来说都很慢,所以大部分情况下,I/O 操作执行的时间相对于 CPU 计算来说都非常长 ,这种场景我们一般都称为 I/O 密集型计算 和 I/O 密集型计算 相对的就是 CPU 密集型计算,CPU 密集型计算 大部分场景下都是 纯 CPU 计算.
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
package
com.base.demo.design.play;
import
java.util.List;
/**
* @Description: CPU测试
* @BelongsProject: base-demo-design
* @BelongsPackage: com.base.demo.design.play
* @Author: ChenYongJia
* @CreateTime: 2021-08-14 16:13
* @Email: chen87647213@163.com
* @Version: 1.0
*/
public
class
CPUTypeTest
implements
Runnable {
/**
* 整体执行时间,包括在队列中等待的时间
*/
List<Long> wholeTimeList;
/**
* 真正执行时间
*/
List<Long> runTimeList;
private
long
initStartTime =
0
;
/**
* 构造函数
*
* @param runTimeList
* @param wholeTimeList
* @return
* @date 2021/8/14 16:13
* @author ChenYongJia
* @version 1.0
*/
public
CPUTypeTest(List<Long> runTimeList, List<Long> wholeTimeList) {
initStartTime = System.currentTimeMillis();
this
.runTimeList = runTimeList;
this
.wholeTimeList = wholeTimeList;
}
/**
* 判断素数
*
* @param number
* @return boolean
* @date 2021/8/14 16:13
* @author ChenYongJia
* @version 1.0
*/
public
boolean
isPrime(
final
int
number) {
if
(number <=
1
)
return
false
;
for
(
int
i =
2
; i <= Math.sqrt(number); i++) {
if
(number % i ==
0
)
return
false
;
}
return
true
;
}
/**
* 计算素数
*
* @param lower
* @param upper
* @return int
* @date 2021/8/14 16:14
* @author ChenYongJia
* @version 1.0
*/
public
int
countPrimes(
final
int
lower,
final
int
upper) {
int
total =
0
;
for
(
int
i = lower; i <= upper; i++) {
if
(isPrime(i))
total++;
}
return
total;
}
@Override
public
void
run() {
long
start = System.currentTimeMillis();
countPrimes(
1
,
1000000
);
long
end = System.currentTimeMillis();
long
wholeTime = end - initStartTime;
long
runTime = end - start;
wholeTimeList.add(wholeTime);
runTimeList.add(runTime);
System.out.println(
"单个线程花费时间:"
+ (end - start));
}
}
|
I/O 密集型任务:这种任务应用起来,系统会用大部分的时间来处理 I/O 交互,而线程在处理 I/O 的时间段内不会占用 CPU 来处理,这时就可以将 CPU 交出给其它线程使用。因此在 I/O 密集型任务的应用中,我们可以多配置一些线程,具体的计算方法是 2N(CPU 核心数).
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
package
com.base.demo.design.play;
import
java.io.BufferedReader;
import
java.io.File;
import
java.io.FileReader;
import
java.io.IOException;
import
java.util.Vector;
/**
* @Description: IO测试
* @BelongsProject: base-demo-design
* @BelongsPackage: com.base.demo.design.play
* @Author: ChenYongJia
* @CreateTime: 2021-08-14 16:18
* @Email: chen87647213@163.com
* @Version: 1.0
*/
public
class
IOTypeTest
implements
Runnable {
/**
* 整体执行时间,包括在队列中等待的时间
*/
Vector<Long> wholeTimeList;
/**
* 真正执行时间
*/
Vector<Long> runTimeList;
private
long
initStartTime =
0
;
/**
* 构造函数
*
* @param runTimeList
* @param wholeTimeList
*/
public
IOTypeTest(Vector<Long> runTimeList, Vector<Long> wholeTimeList) {
initStartTime = System.currentTimeMillis();
this
.runTimeList = runTimeList;
this
.wholeTimeList = wholeTimeList;
}
/**
* IO操作
*
* @return void
* @date 2021/8/14 16:18
* @author ChenYongJia
* @version 1.0
*/
public
void
readAndWrite()
throws
IOException {
File sourceFile =
new
File(
"D:/test.txt"
);
//创建输入流
BufferedReader input =
new
BufferedReader(
new
FileReader(sourceFile));
//读取源文件,写入到新的文件
String line =
null
;
while
((line = input.readLine()) !=
null
) {
//System.out.println(line);
}
//关闭输入输出流
input.close();
}
@Override
public
void
run() {
long
start = System.currentTimeMillis();
try
{
readAndWrite();
}
catch
(IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long
end = System.currentTimeMillis();
long
wholeTime = end - initStartTime;
long
runTime = end - start;
wholeTimeList.add(wholeTime);
runTimeList.add(runTime);
System.out.println(
"单个线程花费时间:"
+ (end - start));
}
}
|
喜欢折腾的同学可以试试(我贴出来的两段 TEST代码):在不同线程数的情况下,run 方法运行时间的差异。可以通过创建不同数量的线程,线程中 new 该 Test 对象(new 两个 List 传到构造参数里)并提交到线程池。查看并归纳计算得出结果.
学习线程池的实现原理,有助于你更好地理解内容.
在 HotSpot VM 的线程模型中,Java 线程被一对一映射为内核线程。Java 在使用线程执行程序时,需要创建一个内核线程;当该 Java 线程被终止时,这个内核线程也会被回收。因此 Java 线程的创建与销毁将会消耗一定的计算机资源,从而增加系统的性能开销.
除此之外,大量创建线程同样会给系统带来性能问题,因为内存和 CPU 资源都将被线程抢占,如果处理不当,就会发生内存溢出、CPU 使用率超负荷等问题.
为了解决上述两类问题,Java 提供了线程池概念,对于频繁创建线程的业务场景,线程池可以创建固定的线程数量,并且在操作系统底层,轻量级进程将会把这些线程映射到内核.
线程池可以提高线程复用,又可以固定最大线程使用量,防止无限制地创建线程。当程序提交一个任务需要一个线程时,会去线程池中查找是否有空闲的线程,若有,则直接使用线程池中的线程工作,若没有,会去判断当前已创建的线程数量是否超过最大线程数量,如未超过,则创建新线程,如已超过,则进行排队等待或者直接抛出异常.
在不同的业务场景以及不同配置的部署机器中,线程池的线程数量设置是不一样的。其设置不宜过大,也不宜过小,要根据具体情况,计算出一个大概的数值,再通过实际的性能测试,计算出一个合理的线程数量.
到此这篇关于Java线程池大小设置的文章就介绍到这了,更多相关Java线程池大小设置内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://juejin.cn/post/6997566049155547166 。
最后此篇关于Java线程池大小的设置方法实例的文章就讲到这里了,如果你想了解更多关于Java线程池大小的设置方法实例的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
有没有一种方法可以使用标准类型构造函数(例如 int、set、dict、list、tuple 等)以用户定义的方式将用户定义类的实例强制转换为其中一种类型?例如 class Example:
我知道这个问题在Stackoverflow中有很多问题,但是即使有很多答案,这些答案也帮不了我什么,也没有找到答案。 在我的WebAPP中,它可以正常工作,但是当我将其转换为API时,它失败了(主题标
这个问题已经有答案了: Why does the ternary operator unexpectedly cast integers? (3 个回答) 已关闭 9 年前。 最近遇到一个Java的陷
我尝试使用 FirebaseApp.configure() 配置 Firebase,但遇到以下崩溃: *** Terminating app due to uncaught exception 'c
我有一个自连接员工实体类,其中包含与其自身相关的 id、name 和 ref 列。我想创建它的新实例并将其保存到数据库。 首先我创建了一个 Employee 类的实例并将其命名为 manager。然后
我有一个用于添加新公寓的表单,在该表单中我有一个下拉列表,用户可以在其中选择负责的人员。 显然,当您从下拉列表中选择并尝试保存公寓时,我的应用程序认为该人已被修改。它给了我下面的错误,指示我应该首先保
从 Visualforce 页面,我需要检索我们组织的 salesforce 实例的 URL,而不是 Visual Force URL。 例如我需要https://cs1.salesforce.com
我遇到了一些可能的问题答案,但这是关于从 Hibernate 3.4.0GA 升级到 Hibernate 4.1.8 的问题。所以这曾经在以前的版本下工作,我已经四处搜索了为什么它在这个新版本中出现了
似乎一遍又一遍地问这个问题,我仍然找不到解决我问题的答案。我在下面有一个域模型。每个新创建或更新的“安全用户”都需要我确保其具有配置文件,如果没有,则创建一个新的配置文件并分配给它。 配置文件的要求相
我很难调试为什么 JPA 不级联我的 @ManyToMany 关系。我发现的所有答案都与缺少级联语句有关。但我确实拥有它们并且仍然得到: Caused by: org.hibernate.Transi
Play 服务 API 表明有一个叫做 Instance ID 的东西 但是,在 Android Studio 中包含以下内容后,我无法导入 InstanceID 类 compile "com.goo
我正在使用 Seam 框架。我有 2 个实体: 请求.java @Entity @Table(name = "SRV_REQUEST") public class Request { private
This question处理构建一个适当的Monad来自单子(monad)的实例,但仅在某些约束下 - 例如Set .诀窍是将其包装成 ContT ,它将约束推迟到包装/展开其值。 现在我想对 Ap
我正在尝试执行此查询: StringBuffer sb = new StringBuffer(); sb.append("select p from PointsEntity p " + "where
我试图了解是否可以更改我的 hibernate 配置并使用单个 MySQL 实例(而不是我当前拥有的多个 MySQL 实例): 我有一个使用 hibernate 的 Java 应用程序,与 2 个模式
我有一个选项卡滑动布局,其中包括四个选项卡,每个选项卡都有自己的布局和 fragment ,在我的主要 Activity 布局中,viewpager 参与更改选项卡。特定 View (选项卡)在应用程
我看到很多帖子声称他们正在运行 MySql 的 RDS 实例,但无法连接到该实例,但我没有运行 RDS。 我使用 EC2 实例来托管我的 WordPress 博客,该博客是使用 Web 平台安装程序安
因为我在我的 ec-2 实例上的 python 虚拟环境中运行应用程序( Airflow ),并且我想在同一个 ec2 实例上的默认 python 环境中运行命令,所以我认为 ssh 到我自己的实例更
这个问题已经有答案了: How to fix the Hibernate "object references an unsaved transient instance - save the tra
例子: run APP1 .. ... run APP1 ... run APP2 如何在 APP2 中对 Vue 说我需要调用 APP1?
我是一名优秀的程序员,十分优秀!