2011-12-14 6 views
1

クライアントがServerProtocolクラスからの説明を要求する回数を格納しようとしています。共有カウンターが並行サーバー上で予想どおり増分しない

現在、新しいクライアントが参加するたびにカウンタは0から増加します。何か案は?

カウンタクラス:ServerProtocolクラスから

public class Counter { 

private int counter; 

public synchronized int get() { 
    return counter; 
} 

public synchronized void set(int n) { 
    counter = n; 
} 

public synchronized void increment() { 
    set(get() + 1); 
} 
} 

スニペット:

case OPTIONS: 
      if (theInput.equals("1")) { 
       theOutput = "computer program description here -- Another? Y or N"; 
       counter.increment(); 
       System.out.println(counter.get()); 
       state = ANOTHER; 

上記サーバ・クラス内の端末へのカウンタの現在の値を印刷しているのprintln方法

ServerProtocolクラス:

public class ServerProtocol { 

private static final int TERMS = 0; 
private static final int ACCEPTTERMS = 1; 
private static final int ANOTHER = 2; 
private static final int OPTIONS = 3; 
private int state = TERMS; 

public String processInput(String theInput) { 
    String theOutput = null; 

    Counter counter = new Counter(); 

    switch (state) { 
     case TERMS: 
      theOutput = "Terms of reference. Do you accept? Y or N"; 
      state = ACCEPTTERMS; 
      break; 
     case ACCEPTTERMS: 
      if (theInput.equalsIgnoreCase("y")) { 
       theOutput = "1. computer program 2. picture 3. e-book"; 
       state = OPTIONS; 
      } else if (theInput.equalsIgnoreCase("n")) { 
       theOutput = "Bye."; 
      } else { 
       theOutput = "Invalid Entry -- Terms of reference. Do you accept? Y or N"; 
       state = ACCEPTTERMS; 
      } 
      break; 
     case ANOTHER: 
      if (theInput.equalsIgnoreCase("y")) { 
       theOutput = "1. computer program 2. picture 3. e-book"; 
       state = OPTIONS; 
      } else if (theInput.equalsIgnoreCase("n")) { 
       theOutput = "Bye."; 
      } else { 
       theOutput = "Invalid Entry -- Another? Y or N"; 
       state = ACCEPTTERMS; 
      } 
      break; 
     case OPTIONS: 
      if (theInput.equals("1")) { 
       theOutput = "computer program description here -- Another? Y or N"; 
       counter.increment(); 
       counter.get(); 
       state = ANOTHER; 

      } else if (theInput.equals("2")) { 
       theOutput = "picture description here -- Another? Y or N"; 
       state = ANOTHER; 

      } else if (theInput.equals("3")) { 
       theOutput = "e-book description here -- Another? Y or N"; 
       state = ANOTHER; 

      } else { 
       theOutput = "Invalid Entry -- 1. computer program 2. picture 3. e-book"; 
       state = OPTIONS; 
      } 
      break; 
     default: 
      System.out.println("Oops"); 
    } 

    return theOutput; 
} 
} 
+1

クライアントが参加するたびにprocessInputを呼び出していますか?あなたはそのメソッドを呼び出すたびに新しいカウンタを作成しています。 – Megacan

+0

その他の回答に加えて、インクリメントして取得すると、複数のスレッドを同時にインクリメントしてから現在の状態にすることができます。すべてのスレッドは同じカウンタ値を表示します。 AtomicIntegerとそのincrementAndGetメソッドの使用を検討してください。 –

+0

@ Megacanはい、毎回processInputが呼び出されます。以下に述べるように、変数を静的にすることは仕事をするようです – newToJava

答えて

0

頼んでいるのかどうかわかりませんが、カウンターが1つしかないようにしたい場合は、staticにすることができます。これにより、増分されるコピーが1つしかないことが保証されます。それは役に立ちますか?

編集:静的変数hereについて読むことができます。

3

serverprotocolメソッド内のカウンタインスタンスはローカル変数です。したがって、processInputメソッドを呼び出すたびに、カウンタの新しいインスタンスがゼロ値で作成されます。それが理由。

2

processInputを複数回呼び出していますか?

カウンタは静的ではありません。初期化するたびに(例:Counter counter = new Counter())、カウント値は0に再初期化されます。静的にするか、1度しか初期化されないようにしてください。

1

ライフサイクルをServerProtocolに指定していないため、クライアントがサーバーを呼び出すたびに作成されるかどうかわかりません。それはGoogle App Engineのサーブレットです。

少なくとも、定義をCounter counterのメソッドからクラスに移動する必要はありません。だからCounter counterがクラスメンバーになります。

PS。現在のコードではcounterを静的にすることはできますが、将来的には設計から外れてしまいます。

関連する問題