Search code examples
javaconcurrencyatomic

A shared counter is not incrementing as expected on concurrent server


I'm trying to store the number of times any client requests a description from a ServerProtocol class.

Currently, the counter will increment from zero each time a new client joins. Any ideas?

Counter class:

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);
}
}

Snippet from ServerProtocol class:

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

The println method above is printing the current value of counter into the terminal in a Server Class:

ServerProtocol Class:

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;
}
}

Solution

  • Not sure if I get what you're asking, but if you want there to only be 1 counter, you can make it static. This should ensure that there is only 1 copy that gets incremented. Does that help?

    Edit: you can read about static variables here.