자바 8 과 Runtime.getRuntime().availableProcessors()

lambda 표현 식 및 병렬 흐름.정 부 는 네가 쓴 코드 가 더 빨리 실행 된다 고 약속 했다.흐름 은 자동 으로 포크/Join 풀 을 통 해 병행 합 니 다.나 는 자바 8 의 주제 에 관 한 강연 을 들 은 적 이 있 지만,이 매우 중요 한 점 에서 그들 이 모두 말 하 는 것 은 약간 문제 가 있다.나 는 후속 적 인 글 에서 병행 류 에 대해 깊이 있 게 설명 할 계획 이다.그 전에 나 는 먼저 시간 을 들 여 그것 을 자세하게 분석 할 것 이다.이 문제 에 대하 여 나 는 단지 당신들 에 게 매우 간단 한 문 제 를 묻 고 싶 을 뿐 이지 만,매우 중요 한 문제 이기 도 합 니 다.왜냐하면 그것 은 많은 문제 의 관건 이기 때 문 입 니 다.이 문 제 는:
이 병렬 작업 의 스 레 드 는 모두 어디에서 왔 습 니까?
자바 8 에서 우 리 는 통용 되 는 포크/조 인 트 탱크 가 있 습 니 다.우 리 는 포크 조 인 트 폴.comonPool()를 통 해 그것 을 방문 하여 물 어 볼 수 있 습 니 다.병렬 흐름,병렬 정렬,CompletableFuture 등 이 사용 된다.포크/Join 풀 을 만 들 때 보통 최대 스 레 드 수 를 지정 하지 않 습 니 다.당신 은 단지 원 하 는 병발 수 를 지 정 했 을 뿐 입 니 다.즉,실행 할 때 같은 시간 에 얼마나 활발 한 스 레 드 가 있 기 를 바 라 는 것 입 니 다.스 레 드 가 하나의 phaser 에 막 혔 을 때 연못 에 충분 한 활성 스 레 드 가 있 도록 다른 스 레 드 를 만 듭 니 다.이 phaser 는 이 행동 을 촉발 시 키 는 동기 화 장치 입 니 다.포크/Join 탱크 의 가장 큰 스 레 드 수 는 32767 이지 만 이 수량 에 이 르 지 못 했 을 때 대부분의 운영 체제 에서 OutOf Memory Error 이상 을 던 집 니 다.이 예제 코드 에서 저 는 새로운 RecursiveAction 을 계속 만 들 것 입 니 다.만약 우리 가 더 큰 숫자 로 증가한다 면,예 를 들 어 100000 을 말 하면 이 코드 는 실패 할 것 이다.

import java.util.concurrent.*;

public class PhaserForkJoin {
 public static void main(String... args) {
  ForkJoinPool common = ForkJoinPool.commonPool();
  Phaser phaser = new Phaser(200);
  common.invoke(new PhaserWaiter(phaser));
 }

 private static class PhaserWaiter extends RecursiveAction {
  private final Phaser phaser;

  private PhaserWaiter(Phaser phaser) {
   this.phaser = phaser;
   System.out.println(ForkJoinPool.commonPool().getPoolSize());
  }

  protected void compute() {
   if (phaser.getPhase() > 0) return; // we've passed first phase
   PhaserWaiter p1 = new PhaserWaiter(phaser);
   p1.fork();
   phaser.arriveAndAwaitAdvance();
   p1.join();
  }
 }
}

포크/Join 탱크 는 최대 스 레 드 수가 하나 도 없고 하나의 기대 병발 수 만 있 습 니 다.이것 은 우리 가 동시에 몇 개의 활성 스 레 드 가 있 기 를 바 라 는 것 을 말 합 니 다.
유 니 버 설 풀 은 서로 다른 유형의 작업 이 같은 풀 을 공유 할 수 있 음 을 의미 하기 때문에 코드 가 작 동 하 는 기계 에서 기대 하 는 병발 수 를 초과 하지 않 아 도 된다.물론 하나의 스 레 드 가 비 Phaser 의 다른 원인 으로 막 히 면 이 유 니 버 설 탱크 의 표현 은 예상 한 것 과 다 를 수 있 습 니 다.
통용 FJ 탱크 의 기본 기대 병발 수 는 무엇 입 니까?
일반적인 FJ 풀 의 기대 병발 수의 기본 값 은 Runtime.getRuntime().availableProcessors()-1 입 니 다.만약 쌍 핵 기계 에서 Arrays.parallelsert()를 통 해 병렬 정렬 을 실행한다 면,기본적으로 일반적인 Arrays.sort()방법 을 사용 합 니 다.비록 Oracle 의 공식 문 서 는 성능 향상 을 약속 할 수 있 지만,당신 은 쌍 핵 기계 에서 어떠한 향상 도 보지 못 할 것 입 니 다.
그러나 더 큰 문 제 는 Runtime.getRuntime().availableProcessors()도 원 하 는 수 치 를 되 돌 릴 수 있 는 것 이 아니다.예 를 들 어 나의 쌍 핵 1-2-1 기계 에서 그것 이 돌아 온 것 은 2 이 고 이것 은 옳다.하지만 제 1-4-2 기계 에 서 는 CPU 슬롯,4 핵,핵 당 2 개의 초 스 레 드 가 있 습 니 다.그러면 8 로 돌아 갑 니 다.그러나 저 는 사실 4 개의 핵 만 있 습 니 다.만약 에 코드 의 병목 이 CPU 에 있다 면 저 는 7 개의 스 레 드 가 더 합 리 적 인 4 개의 스 레 드 가 아니 라 CPU 주 기 를 동시에 경쟁 할 것 입 니 다.만약 나의 병목 이 메모리 에 있다 면,이 테스트 는 내 가 7 배의 성능 을 향상 시 킬 수 있다.
근 데 아직 안 끝났어!자바 Champions 의 한 형 제 는 한 가지 상황 을 발견 했다.그 는 16-4-2 의 기계(즉,16 개의 CPU 슬롯,각 CPU 4 개의 핵,각 핵 두 개의 초 스 레 드,돌아 오 는 값 은 뜻밖에도 16 이다!내 i7 맥 북 프로 의 결 과 를 보면 16*4*2=128 로 돌아 가 야 한다 고 생각한다.이 기계 에서 자바 8 을 실행 하면 통용 되 는 FJ 풀 의 병발 수 를 15 로 만 설정 합 니 다.브 라 이언 고 츠 가 지적 한 바 와 같이 가상 컴퓨터 는 프로세서 가 무엇 인지 잘 모 르 고 운영 체제 에 값 을 되 돌려 달라 고 요청 할 뿐이다.마찬가지 로 운영 체제 도 어떻게 된 일 인지 묻 는 하드웨어 장치 다.하드웨어 는 보통 하드웨어 스 레 드 수 를 알려 줍 니 다."운영 체 제 는 하드웨어 가 말 하 는 것 을 믿 고 가상 컴퓨터 는 운영 체제 가 말 하 는 것 을 믿는다."
다행히 해결 방안 이 하나 더 있다.시작 할 때 시스템 속성 자바 util.concurrent.ForkJoinPool.comon.parallelism 을 통 해 유 니 버 설 풀 의 병발 수 를 설정 할 수 있 습 니 다.즉,우 리 는-Djva.util.concurrent.ForkJoinPool.comon.parallelism=128 을 통 해 이 프로그램 을 시작 할 수 있 습 니 다.이 제 는 병발 수가 128 인 것 을 볼 수 있 습 니 다.

import java.util.concurrent.*;

public class ForkJoinPoolCommon {
 public static void main(String... args) {
  System.out.println(ForkJoinPool.commonPool());
 }
}
유 니 버 설 탱크 를 제어 하 는 추가 시스템 속성 도 두 개 있다.캡 처 되 지 않 은 이상 을 처리 하고 싶다 면 자바 util.concurrent.ForkJoinPool.comon.exception Handler 를 통 해 처리 류 를 지정 할 수 있 습 니 다.스 레 드 공장 이 있 기 를 원한 다 면 자바 util.concurrent.ForkJoinPool.comon.threadFactory 를 통 해 설정 할 수 있 습 니 다.기본 포크/Join 탱크 의 공장 은 수호 라인 을 생 성 합 니 다.아마도 응용 프로그램 에서 사용 하고 싶 지 않 을 것 입 니 다.하지만 그렇게 한다 면 조심 하 세 요.그러면 이 통용 탱크 를 닫 을 수 없습니다.
자바 8 과 Runtime.getRuntime().availableProcessors()에 대한 자세 한 설명 은 여기까지 입 니 다.더 많은 자바 8 과 Runtime.getRuntime().availableProcessors()내용 은 저희 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 도 많은 응원 부 탁 드 리 겠 습 니 다!

좋은 웹페이지 즐겨찾기