Java 8自动使用多核?

我在一年前做了一些关于java 7多核的测试。首先,我只在主线程中实现了一些计算(CPU使用率表明只有一个核完成了所有工作)然后我用ExecutorService实例实现了Callable。 在运行它时,所有核心都在进行工作。

现在,一年后,我必须实现一个插入大量数据的小程序(使用java 8)。 所有工作都在主线程中实现(没有Callable和ExecutorService),但是当我运行程序时,CPU使用情况显示,所有4个内核都是98%。

那么java 8会自动在所有CPU内核上分配工作吗? 我很困惑…

这里有一些代码……

MapGenerator.java

Region[][] regions = new Region[numOfRegions][numOfRegions]; for(int x = 0; x < regions.length; x++){ for(int z = 0; z < regions[x].length; z++){ newLat = SRTMHandler.getNewLatitude(startLat, z * regionSize * 16); newLon = SRTMHandler.getNewLongitude(startLon, x * regionSize * 16, newLat); regions[x][z] = new Region(x, z, regionSize, newLat, newLon); } } 

Region.java:

 private Chunk[] chunks; public Region(int x, int z, int size, float startLat, float startLon){ this.chunks = new Chunk[this.size][this.size]; //Init stuff float newLat = this.startLat, newLon = this.startLon; for(int newX = 0; newX < this.size; newX++){ for(int newZ = 0; newZ < this.size; newZ++){ newLat = SRTMHandler.getNewLatitude(this.startLat, newZ * 16); newLon = SRTMHandler.getNewLongitude(this.startLon, newX * 16, newLat); this.chunks[newX][newZ] = new Chunk(this.x * this.size + newX, this.z * this.size + newZ, 16, 900, this, newLat, newLon); } } } 

Chunk.java:(SRTMHandler.getHeightForLatLon()执行一些地理计算然后读取字节数组中的值,没什么特别的)

 public Chunk(int x, int z, int size, int height, Region r, float startLat, float startLon){ this.blocks = new Block[size][size][height]; //Init stuff try { this.calcSurface(); //System.out.println("Finished " + this.toString()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void calcSurface() throws IOException{ int x1 = this.x; int x2 = this.x + 16; int z1 = this.z; int z2 = this.z + 16; final int radius = 45; float q11 = SRTMHandler.getHeightForLatLon(SRTMHandler.getNewLatitude(this.startLat, (-1)*radius), SRTMHandler.getNewLongitude(this.startLon, (-1)*radius, this.startLat)); float q12 = SRTMHandler.getHeightForLatLon(SRTMHandler.getNewLatitude(this.startLat, radius), SRTMHandler.getNewLongitude(this.startLon, (-1)*radius, this.startLat)); float q21 = SRTMHandler.getHeightForLatLon(SRTMHandler.getNewLatitude(this.startLat, (-1)*radius), SRTMHandler.getNewLongitude(this.startLon, radius, this.startLon)); float q22 = SRTMHandler.getHeightForLatLon(SRTMHandler.getNewLatitude(this.startLat, radius), SRTMHandler.getNewLongitude(this.startLon, radius, this.startLat)); for(int x = 0; x < this.blocks.length; x++){ for(int z = 0; z < this.blocks[x].length; z++){ float height = Interpolation.biLerp(x, z, q11, q12, q21, q22, x1, x2, z1, z2); this.blocks[x][z][(int)Math.round(height)] = new Block(this.x * this.size + x, this.z * this.size + z, (int)Math.round(height), BlockType.Grass, this); } } } 

Java 8不会自动在所有CPU核心上分配工作,除非您的代码明确地请求它(例如通过使用并行流)。

在某些特殊情况下,Hotspot编译器将自动对代码进行矢量化 ,例如参见JDK-6340864 。 但是,自动矢量化使用特殊的SIMD CPU指令,而不是多个CPU。

另见这些答案:

  • JVM是否有能力检测并行化的机会?
  • 自动并行化

(请注意,我重写了答案,删除了由评论更正的部分)

我也经历过这种情况。 就我而言,频繁的垃圾收集导致CPU使用率显着提高(98%)。 正如原始问题下的几条评论所指出的那样,java GC默认使用multithreading。

在我看来,你的程序不受CPU限制。 因此,它不可能完全使用4个核心。 另一方面,当没有为您的程序分配足够的堆空间时,频繁的GC将很容易耗尽CPU资源。 增加堆大小后,一切都很好。