Java Fork/Join 프레임워크

4285 단어 JavaFork/Join
Fork/Join 프레임워크는 Executor Service 인터페이스의 구현입니다. 이를 통해 우리는 다중 프로세스를 실현할 수 있습니다.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의 람다 특성의 일부입니다.

좋은 웹페이지 즐겨찾기