2012-01-05 4 views
0

私のプログラムでは、たくさんの写真の配列リストを繰り返し処理し、それらの外観や画像の種類を変更したり、それらをディスクに書き込みます。私の質問は、複数のスレッドを追加して画像を処理したり、画像を保存したりすることです。もしそうなら、何が最良の方法でしょうか。 ArrayList images = new ArrayList(); // 500以上の画像 ArrayList paths = new ArrayList(); int len = images.size();もっと多くのスレッドを追加すると私のプログラムのパフォーマンスが向上する

for (int i =0; i < len ; i ++) 
{ 
BufferedImage image = process (images.get(i))//takes about a second 
ImageIO.write(image, "jpg", new File(getImagePaths().get(i))); 


} 
+5

あなたが改善しようとしているコードのサンプルは、コミュニティが助けることができる確率を高めます。 :)あなたの記述に基づいて、それは複数のスレッドが助けにならない場合のディスクI/Oかもしれません。パフォーマンスのボトルネックがどこにあるかを判断するためにアプリのプロファイリングを試しましたか? –

+0

あなたがプロセスをCPUに束縛しているとすれば、 'Runtime.availableProcessors()'と 'execute()'のコアと同じ数のスレッドを持つ 'Executors.newFixedThreadPool'を使うでしょう。 –

+1

@GregHewgillもし私たちが彼らから遠ざかっていたら、私たちはそれらをどうやって学ぶのですか? – Skeptor

答えて

3

あなたがリストのサイズのブロックを持っている/ nであり、あなたがして、n個のスレッドがこれらの「ブロック」上で動作していることができるように、あなたはn個のブロックにあなたのリストを分割することができ画像のこれにより、同時に実行できる作業が増えます。

単一のスレッド実行では最初のミスとブロックでエラーが発生し、2番目のイメージなどを読み込むためにフォルトが発生するため、発生したいくつかの問題に対処するためにI/O同時実行性も向上する可能性があります。マルチスレッドのやり方では、一度にn個のイメージをブロックするので、I/Oスケジューラは一度に多くのI/Oを処理できます(一般的には良いことです)。これは、I/Oスレッドの待機が待機している間に、I/Oの重複とコアで実行するスレッドの数が増えるため、シングルコアプロセッサでもパフォーマンスが向上することを意味します。

+2

確かに、それに十分なRAMがあるか、問題はディスクI/Oではない、あるいはそれは単一のコアマシンではない、あるいはそれを効率的にすることができない他の多くのことである。 OPの質問は本当に広すぎ、有用な情報がなく、スレッドの理解が明らかに限られています。 –

+0

@BrianRoachあなたは正しいです。私は多くのことを想定しています。ディスクI/Oは問題になる可能性がありますが、マルチスレッドはI/Oミ​​スとそれに続くブロッキングコールよりもはるかに多くの同時I/Oを引き起こし、単一のコアマシンでも助けて。 –

2

はい、それは非常に可能性があるため:

1)お使いのコンピュータは、おそらく2〜4のCPUまたはコアを持つ

2)画像処理一般的に集中的CPUがある

3)したがって、大きなCPU負荷は、同時に実行される複数のタスクに分割することができます。

これはいつも動作しますか?

いいえあなたのプロセスがI/O(インターネット、ディスクまたはメモリ)境界にある場合(イメージあたり2Gのメモリが必要な場合、または一時ファイルをたくさん書き込む必要がある場合)、 CPU速度の向上はI/Oを行う時間によって相殺され、画像処理の負荷を分担しなければならないプロセッサの数に関係なくプログラムが遅くなるため、直線的な速度向上が見られます。 麺を作るのと同じように - 麺を茹でるのに10分かかります。一度に8つのバーナーがすべて使用されていても、麺に吸収される水分はまだ10分かかります。

擬コード:

//just a reminder ! 
    public static final int MAX_SEM=8; 
    processAll() 
    { 
    //create a new semaphore with 4 slots. 
    semaphore = new Semaphore(MAX_SEM) ; 
    while(! images.empty()) 
     if(semaphore has a slot) 
      Image img=images.pop(); 
      sempahore.decrement() 
      Thread().run(new Runable() { public void run() {process(img);} } 
     else 
      Thread.sleep(1000); 
    } 

    process(Image i) 
    { do some work on i 
     semaphore.increment() 
    } 
+0

私は40種類のスレッドのように追加したらどうなるでしょうか? – user4090

+0

コア/プロセッサが40個ある場合は、それを実行します。最初のものが最後のものより優先度が高いことを確認してください。そのため、ハードディスクは一日中動作せず、スレッドは何も得られません。 – SHiRKiT

+0

kはちょうどそのようなことを試しましたが、実際には私は本当にevreyの単一のiamgeのスレッドを作成できませんか、または私は試してみて、ちょうど多分4をしていると思うのです。 – user4090

関連する問題