2016-08-27 3 views
0

안드로이드 애플 리케이션에서 일하는 동안 나는 무언가를 비틀 거리며 주제에 대한 귀하의 의견/도움을 얻고 싶었습니다.안드로이드 - 스레드, Runnable 및 동시 데이터 액세스

그래서 기본적으로 여러 스레드에서 실행되는 여러 개의 Runnable을 생성합니다. 이 모든 RunnableRunnable을 실행하는 클래스 SomeClassApplyContrast(...) 메서드를 호출합니다 (다소 차이는 있지만 동시에 발생 함). 이 ApplyContrast(...) 메서드는 SomeClassint[]에 액세스하여 수정합니다.

제가 이것이 이것이/문제가 될 수 있는지 궁금합니다. 두 개 이상의 스레드에서 실행할 때 예상되는 결과를 얻지 못하기 때문에이를 묻습니다.

P.S : (: P 또는 그것을 어떻게해야되지 않음)

어떤 도움을 환영합니다 스레드가 배열의 동일한 부분에 접근하지 않는 int[]에 대한 동시 액세스가 있지만. 더 많은 정보가 필요하면 그냥 물어보십시오.

public class SomeClass extends SomeOtherClass { 

    // The number of threads that will be used to do the data processing 
    private static int mNumberOfThreadsToCreate = 10; 

    private int mPixelArrayLength; 

    private int mRunningThreadCount; 

    public SomeClass(AnotherClass callback, int[] pixels, int length) { 
     super(callback, pixels); 

     mPixelArrayLength = length; 
     mRunningThreadCount = mNumberOfThreadsToCreate; 
    } 

    public void run() { 
     new Thread(new Runnable() { 
      public void run() {  
       final int lenByChunk = mPixelArrayLength/mNumberOfThreadsToCreate; 
       for (int i = 0; i < mNumberOfThreadsToCreate; ++i) { 
        int len = lenByChunk; 
        if (i == (mNumberOfThreadsToCreate - 1)) 
         len += (mPixelArrayLength - mNumberOfThreadsToCreate * lenByChunk); 
        applyToChunk(mPixels, i * lenByChunk, len, 128); 
       } 
      } 
     }).start(); 
    } 

    private void applyToChunk(final int[] pixels, final int offset, final int len, final int contrastLevel) { 
     new Thread(new Runnable() { 
      public void run() { 
       applyContrast(pixels, offset, len, contrastLevel);  
       --mRunningThreadCount;  
       onFinish(); 
      } 
     }).start(); 
    } 

    //set value in range 0 - 255 
    private int keepInRange(int colorValue) { 
     if (colorValue < 0) 
      colorValue = 0; 
     else if (colorValue > 255) 
      colorValue = 255; 

     return colorValue; 
    } 

    /** 
    * contrastLevel should be in <-128, 128> range 
    */ 
    private void applyContrast(int[] pixels, int offset, int pixelsLen, int contrastLevel) { 
     double correctionFactor = 259.047619047619; 
     double factor = (correctionFactor * (contrastLevel + 255))/(255 * (correctionFactor - contrastLevel)); 

     for(int i = offset; i < pixelsLen; ++i) { 

      int red = keepInRange((int)(factor * (Color.red(pixels[i]) - 128) + 128)); 
      int green = keepInRange((int)(factor * (Color.green(pixels[i]) - 128) + 128)); 
      int blue = keepInRange((int)(factor * (Color.blue(pixels[i]) - 128) + 128)); 
      int alpha = Color.alpha(pixels[i]); 
      pixels[i] = Color.argb(alpha, blue, green, red);//invert sequence here. 
     } 
    } 

    private void onFinish() { 
     // Shouldn't be < 0 or there is a really serious problem ... 
     if (mRunningThreadCount <= 0 && super.mCallback != null) { 
      super.mCallback.onFinish(super.mPixels); 
     } 
    } 
} 

업데이트 # 1 :

이 (잘못된) 결과가 무엇인지에 대해 좀 더 정보를 추가하려면 : 제가 위에서 말했듯이

, 나는 때마다 예상 결과를 얻을하지 않습니다 데이터 처리는 여러 스레드에서 수행합니다. 데이터 처리가 여러 스레드에서 수행 된 경우 첫 번째 스레드에서 처리 된 데이터가 올바르다. 여기

는 멀티 스레딩 때 얻을 원본 이미지, 예상 결과 및 실제 결과 이미지를 보여주는 일부 사진입니다

(상단 및 이미지의 하단에있는 파란색 부분을 신경 쓰지 마)

원본 이미지 : enter image description here

예상 결과 이미지 : enter image description here

012 3,516,

실제 결과 이미지 : enter image description here

당신은 우리가 "2 부"가 마지막 이미지에서 것을 볼 수 있습니다. 첫 번째 부분 (맨 위)은 첫 번째 스레드에서 처리 한 스레드 (올바르게 수행 됨)이고 나머지 두 번째 스레드에서 처리 된 두 번째 스레드입니다 (이것이 잘못된 것입니다).

답변

0

나는 괜찮다고 생각합니다.

배열 pixels (아마도 mPixels이라는 별칭이 지정됨)은 둘 이상의 스레드에서 액세스됩니다. 그것은 그것이 틀리게 만들 것입니다.

각 스레드가 자체 청크에만 액세스 할 수 있도록 배열에 대한 액세스를 청크하고있는 것처럼 보입니다. 여러 스레드가 어레이의 동일한 지점에 절대 액세스하지 않는 한 코드는 정확합니다.

나는 격렬하게 혼란 스럽다. 변수 len의 이름이 잘못되었다고합니다. 확실히, 동시성 정확성은 결정하기가 정말로 어렵습니다. 나는 그것이 더 명확하게 쓰여질 수 있다고 믿는다. 그래서 오류가 발생하기 쉬운 것으로, 그렇게할만한 가치가있을 것이다.

+0

'len' 변수의 이름이 잘못되었습니다. 나는 내용이 잘못되어 있는지 확인했습니다. 내 게시물을 업데이트했습니다. 시간이 있다면 좀보세요. – Moucheg