2017-06-29 8 views
-4

言語のためのデータ構造を提案します基本的にはそれ以上の実行を決定するでしょう。私は複数のスレッドから出力された質問を混在させたくないので、別のタスク/スレッドが固定レートで実行されます(さらにメインスレッドとも呼ばれます)。質問を取得して質問に表示することができますユーザー。スレッドによって要求される質問の数は様々であり、質問が応答を得ると、それはもはやもう必要なくなります。は、このユースケース

私の現在の実装では、LinkedTransferQueueを使用しています。これは、基本的にメインスレッドと質問スレッドの間でポーリングを待たずにデータを共有できるようにします。

LinkedTransferQueue<String>を含むTaskクラスの同期ArrayListを作成しました。スレッドは新しいTaskを作成し、その質問をtransfer()メソッドでキューに追加します。メインスレッドはそれらをピックアップし、同じキューに戻されるユーザーからの応答を取得します。ここでの利点は、LinkedTransferQueuetake()メソッドを提供していて、ポーリングなしで待機できることです。

他のアプローチには、値がメインスレッドによって更新され、常に他のスレッドによってポーリングされる変数volatile sharedを使用することが含まれます。

他のデータ構造が利用可能かどうかをご提案ください。これは私が理解できるものから、生産者 - 消費者の問題ではありません。他に懸念がある場合は質問を投稿してください。

ありがとうございます!

+0

私は広さの理由を理解していません。私は将来の質問に注意を払うことができるように正当化してください。 私は完全に私のために働くアンドレアスからの答えを得ました! – LearningToCode

答えて

0

スレッドが回答を待つようにするために、質問テキストを持つ質問オブジェクトを作成し、その回答を保存し、その答えが利用可能なときに追跡するためにCountDownLatchがあることをお勧めします。

public final class Question { 
    private final String question; 
    private String   answer; 
    private CountDownLatch latch = new CountDownLatch(1); 

    public Question(String question) { 
     this.question = question; 
    } 
    public String getQuestion() { 
     return this.question; 
    } 
    public String getAnswer() throws InterruptedException { 
     this.latch.await(); 
     return this.answer; 
    } 
    public void setAnswer(String answer) { 
     this.answer = answer; 
     this.latch.countDown(); 
    } 
} 

あなたのワーカースレッドは、その後、例えば、メインQueueにその質問を送り、返事を待つことができますメインスレッドは、例えば、その後の質問を待つBlockingQueueのいくつかの種類を使用して、一度にそれらを1つずつ処理する

public final class Worker implements Runnable { 
    private final Queue<Question> queue; 
    private final int    delayInSeconds; 
    private final String[]  questions; 

    public Worker(Queue<Question> queue, int delayInSeconds, String... questions) { 
     this.queue = queue; 
     this.delayInSeconds = delayInSeconds; 
     this.questions = questions; 
    } 
    @Override 
    public void run() { 
     List<String> answers = new ArrayList<>(); 
     try { 
      for (String question : this.questions) { 
       Thread.sleep(this.delayInSeconds * 1000L); 
       Question q = new Question(question); 
       this.queue.add(q); 
       String answer = q.getAnswer(); 
       answers.add(answer); 
      } 
     } catch (InterruptedException unused) { 
      System.out.println("Interrupted"); 
     } 
     System.out.println(answers); 
    } 
} 

このように:

public static void main(String[] args) throws Exception { 
    BlockingQueue<Question> queue = new LinkedBlockingQueue<>(); 
    Worker w1 = new Worker(queue, 3, "Can you play poker?", 
            "Can you juggle?", 
            "Can you summersault?"); 
    Worker w2 = new Worker(queue, 4, "How old are you?", 
            "How tall are you?"); 
    new Thread(w1).start(); 
    new Thread(w2).start(); 
    Scanner in = new Scanner(System.in); 
    for (int i = 0; i < 5; i++) { 
     Question q = queue.take(); 
     System.out.println(q.getQuestion()); 
     String answer = in.nextLine(); 
     q.setAnswer(answer); 
    } 
} 

サンプル出力

Can you play poker? 
yes 
How old are you? 
13 
Can you juggle? 
no 
How tall are you? 
5 11 
Can you summersault? 
[13, 5 11] 
no 
[yes, no, no] 
+0

'CountDownLatch'は連続してポーリングすることなく、私が取ったよりはるかにクリーンなアプローチです。すばらしいです!! – LearningToCode

関連する問題