Incrementing and decremening a single shared variable with multiple Threads

user2075927 picture user2075927 · Mar 31, 2013 · Viewed 10.6k times · Source

When incrementing and decrementing multiple threads using a single shared variable, how can I ensure that the threads count in a syncronized way and don't skip any value.

I have created a seperate class in which I have 3 different methods, one to increment, another to decrement and the last one to return the value. they are all synchronized as well.

The result shows an example:

  • This is Thread_4 iteration: -108 of 500
    This is Thread_5 iteration: 291 of 500
    This is Thread_4 iteration: -109 of 500
    This is Thread_4 iteration: -110 of 500

As you can see the threads are decrementing but then it jumps to "291" which should not happen as I am using a shared variable.

*******************EDIT********

CODE:- SHARED VARIABLE CLASS

public class shareVar extends Thread
{
    private static int sharedVariable = 0;


    public synchronized static void increment(){
        sharedVariable++;
    }

    public synchronized static void decrement(){
        sharedVariable--;
    }

    public  static int value(){
        return sharedVariable;
    }
}

----- Incrementing Class

sVar incrementVal = new sVar();

public synchronized void display(){

    for(int countVal = 0; countVal<=max; countVal++ ){
            incrementVal.increment();
            System.out.println("This is " + threadName + " iteration: " + incrementVal.value() + " of " + max);
            //this.yield();
    }
    System.out.println("*THIS " + threadName + " IS FINISH " 
                                    + "INCREMENTING *");

}

public void run(){

    display();
}

Answer

Eng.Fouad picture Eng.Fouad · Mar 31, 2013

Consider using AtomicInteger:

public class Foo
{
    private AtomicInteger counter = new AtomicInteger(0);

    public void increment()
    {
        counter.incrementAndGet();
    }

    public void decrement()
    {
        counter.decrementAndGet();
    }

    public int getValue()
    {
        return counter.get();
    }
}

or using the synchronized methods:

public class Foo
{
    private volatile int counter;

    public synchronized void increment()
    {
        counter++;
    }

    public synchronized void decrement()
    {
        counter--;
    }

    public int getValue()
    {
        return counter;
    }
}