Java 消失的可伸缩性

Java 消失的可伸缩性,java,concurrency,Java,Concurrency,我制作了一个玩具程序来测试Java的并发性能。我把它放在这里: 它接受整数作为指示要使用多少线程的参数。这个程序只是从一个范围算出素数。通过注释第44~53行可以得到一个通用版本,它可以生成近乎完美的可伸缩性 但是,当我取消注释第44~53行时(该行在本地进行简单计算),并将变量s调整为足够大的值,可伸缩性可能会消失 我的问题是我的玩具程序是否使用共享数据,这可能会导致并发性能下降。以及如何解释消失的可伸缩性(我认为低水平的开销,如垃圾收集,会导致这种情况)?任何解决方案都可以解决类似这种情况

我制作了一个玩具程序来测试Java的并发性能。我把它放在这里:

它接受整数作为指示要使用多少线程的参数。这个程序只是从一个范围算出素数。通过注释第44~53行可以得到一个通用版本,它可以生成近乎完美的可伸缩性

但是,当我取消注释第44~53行时(该行在本地进行简单计算),并将变量
s
调整为足够大的值,可伸缩性可能会消失


我的问题是我的玩具程序是否使用共享数据,这可能会导致并发性能下降。以及如何解释消失的可伸缩性(我认为低水平的开销,如垃圾收集,会导致这种情况)?任何解决方案都可以解决类似这种情况的问题?

问题代码是:

int s = 32343;
ArrayList<Integer> al = new ArrayList<Integer>(s);
for (int c = 0; c < s; c++) {
    al.add(c);
}
Iterator<Integer> it = al.iterator();
if (it.hasNext()) {
    int c = it.next();
    c = c++;
}
…随着线程数量的增加,它显示了几乎线性的缩放。我解决的问题是上面和John Vint(现已删除)回答中提出的问题,以及不正确/不必要地使用
ConcurrentLinkedQueue
结构和一些有问题的计时逻辑

如果我们启用GC日志记录并分析这两个版本,我们可以看到原始版本运行垃圾收集的时间大约是修改版本的10倍:

Original:  [ParNew: 17401K->750K(19136K), 0.0040010 secs] 38915K->22264K(172188K), 0.0040227 secs]
Modified:  [ParNew: 17024K->0K(19136K),   0.0002879 secs] 28180K->11156K(83008K),  0.0003094 secs]
这对我来说意味着,在常量列表分配和
Integer
autoboxing之间,最初的实现只是搅动了太多的对象,这给GC带来了太多的负载,这将线程的性能降低到了没有任何好处(甚至是负面好处)的地步创建更多线程


所有这些都告诉我,如果你想在Java中获得良好的并发扩展,无论你的任务是大是小,你都必须注意如何使用内存,注意潜在的陷阱和低效,并优化掉低效的部分。

Hi@aroth,在我的例子中,
s
与并发性和可伸缩性有很大关系:这段代码由每个线程重复执行;双线程设置中的每个线程执行它
n/2次
。。。是的,我明白了。问题是这段代码本身实际上什么都不做。它创建或修改的任何状态都不会在其他任何地方使用。因此,代码实际上与任何事情都没有关系,因为运行它没有明显的效果(除了减慢其他一切)。这只是浪费了计算操作。不,它没有任何意义。我添加这段代码是为了模拟一个场景:Java并发很好地支持简单的计算,但不支持不太复杂的计算——开销太高。另一个可能的考虑因素是内存使用。您是否为JVM提供了足够的堆空间,使其可以在内存中为每个线程提供一个
al
实例,而无需在RAM中来回分页数据(或连续进行垃圾收集)?显然,将内容分页到磁盘会降低性能。请注意,垃圾回收在运行时可能会暂停所有线程,对于
s
的较大值,垃圾回收器将有更多的工作要做。在你开始发现问题之前,你必须使
s
多大?是的,我在16核CPU上测试了它。我在另一台8核计算机上测试了相同的设置,可伸缩性再次出现。下次在某处尝试Java并发时,我将使用这个玩具程序进行第一步测试。顺便说一句,计算初始编号的更好方案是让线程共享一个包含候选编号的并发队列,而不是划分线程的范围——我只是想避免在这个玩具程序中共享数据。
Original:  [ParNew: 17401K->750K(19136K), 0.0040010 secs] 38915K->22264K(172188K), 0.0040227 secs]
Modified:  [ParNew: 17024K->0K(19136K),   0.0002879 secs] 28180K->11156K(83008K),  0.0003094 secs]