Java 服务表现问题

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

我试图用Java Executor框架来解决问题,所以我创建了一个任务,它只不过是字符串操作

如下图所示,为循环设置

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秒
2.作业数量(任务)-30000个,每个任务将循环5000个(中午)

  • a、 连续-433.340000000000003秒
  • b执行器框架-大约325秒
3.作业数量(任务)-5000,每个任务将循环15000(中午)

  • a、 串行(单芯)-661秒
  • b执行器框架(多核)-1154秒
在案例1和案例2中,正如预期的那样,它清楚地表明,与串行执行相比,多线程方法占用的时间更少 但案例3几乎相反,所以我有以下问题

1.我们什么时候应该采用串行执行或多线程方法(通过利用使用Exceutor框架的多核机器) 用于处理大量数据(假设我要处理30000条员工记录)

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可能会将其作为未使用的局部变量进行完全优化。