2011-12-14 3 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은 매번 호출됩니다. 아래에 명시된 바와 같이 static 변수를 사용하면 작업을 수행하는 것처럼 보입니다. – newToJava

답변

0

내가 묻는 것을 얻을 수 있는지 확실하지 않지만 카운터가 1 개인 경우에는 static으로 만들 수 있습니다. 이렇게하면 증분 된 복사본이 하나만 있어야합니다. 그게 도움이 되니?

편집 : 정적 변수 here에 대해 읽을 수 있습니다.

3

serverprotocol 메서드 내의 카운터 인스턴스는 로컬 변수입니다. 그래서 processInput 메쏘드를 호출 할 때마다 카운터의 새로운 인스턴스가 0 값으로 생성됩니다. 그게 이유야.

2

processInput을 두 번 이상 호출 하시겠습니까?

카운터가 정적이 아닙니다. 초기화 할 때마다 (예 : Counter counter = new Counter()) 카운트 값이 0으로 다시 초기화됩니다. 정적으로 설정하거나 초기화가 한 번만 초기화되는지 확인하십시오.

1

수명주기를 ServerProtocol으로 지정하지 않았으므로 클라이언트가 서버를 호출 할 때마다 생성되는지는 알 수 없습니다. Google App Engine의 서블릿입니다.

최소한 정의 방법을 클래스에서 Counter counter으로 옮길 필요가 없습니다. 따라서 Counter counter이 클래스 멤버가됩니다.

추신. 현재 코드에서 counter을 정적으로 사용하면 효과가 있지만 예상보다 좋지는 않습니다.