3

これは、実際のスレッド設計に関する一般的な質問です。私は特にAndroidでJavaを使用していますが、この質問の焦点は一般的なデザインの方が適しています。

十分に単純で、スレッド内のメソッドまたはスレッド内のメソッドの方が優れています。

例、

3つのメソッド/関数/何でもあるとしましょう。

public void readMail()
{
    //Logic...
}
public void postQuestion()
{
    //Logic...
}
public void answerQuestion()
{
    //Logic...
}

持っている方がいいですか


A:メソッド内のスレッド

public void readMail()
{
    new Thread(new Runnable()
    {
        public void run()
        {
            //Logic
        }
    }).start();
}

次に、OOの状況で通常行うようにメソッドを呼び出します。言う

Email.readMail();

B:スレッド内のメソッド

//note this could be inside a method or a class that extends runnable
new Thread(new Runnable()
{
    public void run()
    {
        readMail();
        postQuestion();
        answerQuestion();
    }
}).start();
4

5 に答える 5

4

2 番目のオプションは、s などを使用するように書き直されやすいExecutorので、そのバージョンを好みます。

于 2012-04-07T17:05:07.790 に答える
1

私が好む:


C:1つのスレッド1つのオブジェクト

public class Test {
  public static class MailReader implements Runnable {
    public void readMail() {
      //Logic...
    }
    @Override
    public void run() {
      while (!Thread.currentThread().isInterrupted()) {
        readMail();
      }
    }
  }

  public static class QuestionPoster implements Runnable {
    public void postQuestion() {
      //Logic...
    }
    @Override
    public void run() {
      while (!Thread.currentThread().isInterrupted()) {
        postQuestion();
      }
    }
  }

  public static class QuestionAnswerer implements Runnable {
    public void answerQuestion() {
      //Logic...
    }
    @Override
    public void run() {
      while (!Thread.currentThread().isInterrupted()) {
        answerQuestion();
      }
    }
  }
  public static void main(String[] args) throws FileNotFoundException {
    new Thread(new QuestionAnswerer()).start();
    new Thread(new QuestionPoster()).start();
    new Thread(new MailReader()).start();
  }
}

これにより、追加の作業を行うことなく、あらゆる可能性が可能になります。投稿された質問よりも多くのメールに回答したい場合は、MailReadersを増やしてください。

あなたが見たら

for ( int i = 0; i < 10; i++ ) {
  new Thread(new MailReader()).start();
}

あなたは何が意図されているかを正確に知っており、それがうまくいくことを知っています。

于 2012-04-08T15:39:11.033 に答える
0

他のプログラマーが使用するユーティリティを作成する場合、クライアント プログラマーはスレッドをまったく気にせず、シングルスレッド プログラムを書きたいだけかもしれないことに注意してください。そうする非常に正当な理由がない限り、シングルスレッドで正常に動作するプログラムにスレッド化の問題をドラッグするように強制するべきではありません。これは、ライブラリが内部でスレッドを使用できないことを意味しますか? いいえ!ただし、callerには、メソッドはシングル スレッドに見える必要があります(ただし、スレッドなしで実装された場合よりも高速に返されます)。

どうすればこれを行うことができますか?誰かがメソッドの 1 つを呼び出したら、呼び出し元のスレッドをブロックし、並列で実行できるワーカー スレッドのプールにタスクを渡します。ワーカー スレッドがタスクを終了したら、呼び出し元のスレッドのブロックを解除し、呼び出し元に値を返すようにします。

このようにして、呼び出し元にスレッドの問題への対処を強制することなく、並列処理のパフォーマンス上の利点を得ることができます。

一方、ライブラリが内部でスレッドを使用する必要がないと判断した場合でも、クライアント プログラマがスレッドを使用する可能性があるため、ライブラリをスレッド セーフにする必要があります。

つまり、「スレッドイン方式?」の判断に理由はありません。と「スレッド内のメソッド?」結合する必要があります。パフォーマンス上の利点がある場合は「メソッド内のスレッド」を使用できますが、呼び出し元には影響しません。(内部でスレッドを使用しているかどうかを気にすることなく、メソッドを呼び出して必要な戻り値を取得できるはずです)。

モジュールがスレッドセーフである場合、呼び出し元がスレッドを使用しているかどうかに影響されません。そのため、クライアント プログラマーがスレッドを使用したい場合は、「スレッド内のメソッド」も使用できます。状況によっては、「スレッド内メソッド」と「メソッド内スレッド」の両方が存在する場合があります。モジュールが内部でワーカー スレッド プール + タスク キューを使用している可能性があり、複数の呼び出し元スレッドがタスクをキューにプッシュして待機している可能性があります。結果。

さて、私はあなたがライブラリを構築しているように話していますが、実際には、おそらく自分で使用するためのコードを構築しているだけでしょう。しかし、それにもかかわらず、同じ原則が適用されます。パフォーマンスのためにスレッドを使用したい場合は、スレッドの使用をインターフェースの背後にカプセル化し、モジュール XYZ がスレッドを使用しているかどうかをプログラムの残りの部分が認識または気にする必要がないようにすることをお勧めします。同時に、呼び出し元がスレッドを使用するかどうかを決定できるように、各モジュールをスレッドセーフにするのが最善です。

于 2012-04-07T18:47:44.147 に答える
0

最初の設計 (A) では、実際にはすべてのメソッドが個別のスレッドですが、2 番目の設計 (B) ではスレッドが 1 つしかありません。
アプリケーションロジックとすべてのメソッドが実行する操作に大きく依存します
。メソッドを並行して実行する必要がある場合は A が正解ですが、すべてのメソッドをスレッドで順番に実行する必要がある場合は B を選択してください。

于 2012-04-07T17:13:53.667 に答える