Java Fork/Join 프레임워크
모든 Executor Service 인터페이스의 실현과 마찬가지로, Fork/Join도 스레드 탱크를 사용하여 분포식 관리 작업 스레드를 사용합니다.Fork/Join 프레임워크의 독특한 점은 Work-stealing 알고리즘을 사용했다는 점이다.이 알고리즘을 통해 작업 라인은 할 일이 없을 때 다른 바쁜 라인을 훔쳐서 수행할 수 있다.
Fork/Join 프레임워크의 핵심은 ForkJoinPool 클래스, AbstractExecutor Service 클래스의 하위 클래스입니다.ForkJoinPool은 핵심적인work-stealing 알고리즘을 실현하고 ForkJoinTask 처리를 실행할 수 있습니다.
기초용법
Fork/Join 프레임워크를 사용하는 첫 번째 단계는 조각 작업을 수행하는 코드를 작성하는 것입니다.작성할 코드는 다음과 같은 위조 코드와 유사합니다.
if :
else:
ForkJoinTask 하위 클래스를 사용하여 위의 코드를 봉인합니다. 보통 JDK가 제공하는 클래스를 사용합니다. 사용하는 클래스는 RecursiveTask (이 클래스는 결과를 되돌려줍니다) 와 RecursiveAction 두 종류입니다.ForkJoinTask 하위 클래스를 준비한 후 모든 작업을 대표하는 대상을 만들고 이를 ForkJoinPool의 실례적인 invoke () 방법에 전달합니다.
모호함에서 선명함까지
Fork/Join 프레임워크가 어떻게 작동하는지 이해하는 데 도움을 주기 위해 우리는 하나의 사례를 사용하여 설명한다. 예를 들어 한 장의 그림을 모호하게 처리하는 것이다.우리는 하나의 정형 수조로 그림을 표시하는데, 그 중의 모든 수치는 픽셀의 색을 대표한다.희미해진 그림도 같은 길이의 수조로 표시한다.
실행 모호성은 그림을 대표하는 모든 픽셀을 처리함으로써 이루어진다.각 픽셀과 그 주위 픽셀의 균일치(빨간색과 노란색, 파란색 삼원색의 균일치)를 계산하면 생성된 결과 수조가 모호한 그림이다.이미지를 대표하는 것은 통상적으로 하나의 대수 그룹이기 때문에 전체 처리 과정은 통상적으로 많은 시간을 필요로 한다.Fork/Join 프레임워크를 사용하여 멀티프로세서 시스템의 병렬 처리 장점을 활용하여 속도를 높일 수 있습니다.다음은 가능한 실현이다.
package com.zhyea.robin;
import java.util.concurrent.RecursiveAction;
public class ForkBlur extends RecursiveAction {
private int[] mSource;
private int mStart;
private int mLength;
private int[] mDestination;
// ; .
private int mBlurWidth = 15;
public ForkBlur(int[] src, int start, int length, int[] dst) {
mSource = src;
mStart = start;
mLength = length;
mDestination = dst;
}
protected void computeDirectly() {
int sidePixels = (mBlurWidth - 1) / 2;
for (int index = mStart; index < mStart + mLength; index++) {
// .
float rt = 0, gt = 0, bt = 0;
for (int mi = -sidePixels; mi <= sidePixels; mi++) {
int mindex = Math.min(Math.max(mi + index, 0), mSource.length - 1);
int pixel = mSource[mindex];
rt += (float) ((pixel & 0x00ff0000) >> 16) / mBlurWidth;
gt += (float) ((pixel & 0x0000ff00) >> 8) / mBlurWidth;
bt += (float) ((pixel & 0x000000ff) >> 0) / mBlurWidth;
}
// .
int dpixel = (0xff000000) |
(((int) rt) << 16) |
(((int) gt) << 8) |
(((int) bt) << 0);
mDestination[index] = dpixel;
}
}
....
}
현재 추상적인 방법인compute()를 실현하고 이 방법에서 모호한 조작을 실현할 뿐만 아니라 하나의 임무를 두 개의 작은 임무로 나누는 것도 실현했다.이것은 단지 수조의 길이에 근거하여 직접 임무를 수행할 것인지, 아니면 그것을 두 개의 작은 임무로 나눌 것인지를 결정할 뿐이다.
protected static int sThreshold = 100000;
protected void compute() {
if (mLength < sThreshold) {
computeDirectly();
return;
}
int split = mLength / 2;
invokeAll(new ForkBlur(mSource, mStart, split, mDestination),
new ForkBlur(mSource, mStart + split, mLength - split,
mDestination));
}
위의 방법은 Recursive Action의 하위 클래스에 정의되어 있기 때문에 ForkJoinPool에서 작업을 직접 만들고 실행할 수 있습니다.구체적인 단계는 다음과 같다.1. 수행할 작업을 나타내는 객체를 만듭니다.
// src
// dst
ForkBlur fb = new ForkBlur(src, 0, src.length, dst);
2. 작업을 실행하는 ForkJoinPool 인스턴스를 만듭니다.ForkJoinPool pool = new ForkJoinPool();
3. 작업 실행:pool.invoke(fb);
원본 코드에는 목표 그림을 만드는 코드도 포함되어 있습니다.자세한 내용은 ForkBlur 예제를 참조하십시오.표준 구현
Fork/Join 프레임워크를 사용하여 사용자 정의 알고리즘에 따라 멀티코어 시스템에서 작업을 수행하려면 당연히 사용자 정의 클래스를 실현해야 한다. (예를 들어 이전에 우리가 실현한 ForkBlur 클래스)이외에도 JavaSE에서는 Fork/Join 프레임워크의 일부 기능을 널리 사용하고 있습니다.예를 들어 자바8의 자바.util.Arrays 클래스의parallelSort() 방법은 Fork/Join 프레임워크를 사용합니다.자세한 내용은 Java API 문서를 참조하십시오.
Fork/Join 프레임워크의 또 다른 구현은java에 있습니다.util.streams 패키지, 이것도 자바8의 람다 특성의 일부입니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.