자바 8 과 Runtime.getRuntime().availableProcessors()
이 병렬 작업 의 스 레 드 는 모두 어디에서 왔 습 니까?
자바 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()내용 은 저희 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 도 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Java 8 새 기능 내장 함수식 인터페이스 상세 정보Java 8 새로운 기능 내장 함수식 인터페이스 이전의 블로그 람다 표현식에서 자바 8이 제공하는 함수식 인터페이스를 언급한 적이 있다.이 글에서 자바 8의 가장 기본적인 함수식 인터페이스를 소개할 것이다 방법의 인...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.