Java 服务表现问题
我试图用Java Executor框架来解决问题,所以我创建了一个任务,它只不过是字符串操作 如下图所示,为循环设置Java 服务表现问题,java,multithreading,concurrency,multiprocessing,executorservice,Java,Multithreading,Concurrency,Multiprocessing,Executorservice,我试图用Java Executor框架来解决问题,所以我创建了一个任务,它只不过是字符串操作 如下图所示,为循环设置 for(int i = 0; i < noOfTimes; i++) str = str + 't'; for(int i=0;iTask.Java 2.Main.Java->ThreadTask.Java刚刚将测试用例更改为no of Task=1000000,每个任务都将循环1000000次操作(int a=10/10)。结果让人大吃一惊。按顺序,它花费了=6
for(int i = 0; i < noOfTimes; i++)
str = str + 't';
for(int i=0;i
现在我的计划是串行(使用for循环逐个)和并行(使用Executor框架,一次提交所有作业并让它运行)执行此任务
然后比较它们的性能。所以我执行了下面的测试用例。我有一台带有8GB RAM和处理器的机器——英特尔i7,我认为它有8个内核
1.作业数量(任务)-30000,每个任务将循环1000(中午)
- a、 连载-21.619
- b执行器框架-大约13.8秒
- a、 连续-433.340000000000003秒
- b执行器框架-大约325秒
- a、 串行(单芯)-661秒
- b执行器框架(多核)-1154秒
2.我在上面的测试案例中观察到,如果单任务处理不耗时(循环1000次),多线程方法的速度要快得多 但一旦我增加了单个任务的处理时间(循环15000),它所花费的时间几乎是串行执行的两倍 3.我想检查上面提到的任务管理器中的CPU使用情况
但是CPU没有利用100%的所有内核?首先,您应该尝试其他测试
String
是不可变的,因此执行str=str+“t”
在时间上实际上不是线性的:只添加一个字符意味着每次都要重建整个字符串
另外,由于Java中的字符串池,我不能100%确定string
是测试并发性的最佳对象
其次,并发性增加了程序的复杂性和计划外行为的风险,如死锁、竞争条件。。。一个糟糕的并行设计很可能不如一个普通的串行设计有效
因此,如果您对自己的程序感到满意,并且具有良好的性能,请不要使用多线程。如果您对性能不满意,首先尝试找出原因并改进串行设计。只有这样,您才能添加多线程,但您确实需要知道自己在做什么 可能您应该发布完整的代码,因为可能存在一些隐藏的拥塞点。对多线程程序进行基准测试并不容易,请参阅以下链接:
str=str+'t'
非常无效(请改用StringBuilder),最糟糕的是,它会分配大量内存。所以你的测试不具代表性。@tigran。我在谷歌硬盘上有共享代码。1.SerialTest.Java->Task.Java 2.Main.Java->ThreadTask.Java刚刚将测试用例更改为no of Task=1000000,每个任务都将循环1000000次操作(int a=10/10)。结果让人大吃一惊。按顺序,它花费了=689秒,使用executor服务(8核)只花费了185秒,CPU使用率几乎达到95%。显然,这表明多线程方法是最好的。这是否意味着如果操作在时间上是线性的,多核总是比串行的表现好。?我应该从这些测试案例中吸取什么教训。@user530158您现在只测试executor-10/10
是一个编译时常量表达式,因此将编译成int a=1
,如果您不进一步使用a
执行任何操作,那么编译器或JIT可能会将其作为未使用的局部变量进行完全优化。