Androidアプリで作業しているうちに、私は何かを見つけたが、その件に関するあなたの意見や助けを得たかった。Android - スレッド、ランナブル、同時データアクセス
基本的に、私は別のスレッドで動作するいくつかのRunnable
を作成しています。これらすべてRunnable
はRunnable
を実行するクラスSomeClass
からApplyContrast(...)
というメソッドを呼び出します(多少なりとも同時に)。 このApplyContrast(...)
メソッドは、同じクラスのint[]
にアクセスして変更します。SomeClass
。
私はこれが問題であるかどうか疑問に思っていましたか? 2つ以上のスレッドでこれを実行すると、期待した結果が得られないため、これを求めています。
P.S:int[]
への同時アクセスがあってもスレッドが配列の同じ部分にアクセスしていない(またはそれを行うことになっていません:P)
すべてのヘルプは大歓迎です。さらに詳しい情報が必要な場合は、尋ねてください。
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);
}
}
}
UPDATE#1:
は(間違った)結果が何であるかについて、もう少し情報を追加するには:私は上記に述べたように
、私はいつでも期待される結果を得ることはありません私はいくつかのスレッドでデータ処理を行います。 データ処理が複数のスレッドで行われた場合最初のスレッドで処理されたデータ(実行されたデータ)は正しいです。ここで
は、マルチスレッド時に私が取得元の画像、期待された結果と実際の結果の画像を表示するためにいくつかの写真です:(一番上と画像の下部にある青色の部分を気にしないでください)
あなたは最後の画像では、我々は「2部」を持っていることがわかります。 1番目の部分(上端)は、1番目のスレッドで処理されたもの(これは正しく行われます)と残りの2番目のスレッドで処理されたもの(これは間違っています)です。
'len'変数の名前が間違っているのは事実です。私はそれが内容であることを確認して、何も間違っていません。 私の投稿を更新しました。時間があれば見てください。 – Moucheg