1
package demo5;

class Process extends Thread {

static int counter = 0;

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

public void run() {
    for (int i = 0; i < 1000000; i++)
    {
        increment();
    }
    System.out.println("Done.");
  }
}

public class App {

public static void main(String[] args) throws InterruptedException {
    Process p1 = new Process();
    Process p2 = new Process();
    p1.start();
    p2.start();

    p1.join();
    p2.join();

    System.out.println("Value of count is :" + p1.counter);

}

}

if I declare the increment function as NON-STATIC function the value of the counter at the end will NOT be 2 million.

on the other hand, it works properly when the increment method is defined as static.

As far as I know there will be only ONE increment function for all the Process objects.. so why do I have to declare it as a static method..?

thanks

6
  • Are you sure your meant counter to be static? Commented Apr 9, 2013 at 14:48
  • you could even add transient keyword to counter and delete synchronized and it will work. Commented Apr 9, 2013 at 14:59
  • @shevchik Transient wouldn't effect it. Do you mean volatile? Even then it wouldn't work. Commented Apr 9, 2013 at 15:05
  • John, you are right, volatile. Why wouldn't work? Commented Apr 9, 2013 at 15:06
  • Because an increment is three operations. Read Increment Write. Volatile helps with visibility of single operations, but since increment is a compound it cannot do anything about it. Commented Apr 9, 2013 at 15:10

2 Answers 2

7

Declaring it static will cause the synchronized to lock on the Process.class instance. So all threads running will block on the Object within the increment method. Removing the static will cause each thread to only block on the Thread instance (which in your case there are two).

As a result your counter variable is being incremented in parallel and as noted many times, int incrementing is not thread-safe.

As far as I know there will be only ONE increment function for all the Process objects

There is one increment function for the Process class, but the synchronization is done on the Object and not the method for instance:

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

Is equivallent to:

class Process{
     public void increment() { 
           synchronized(this){
                  counter++; 
            }
}

Edit: To answer Rouki's question.

class Process{
     public static synchronized void increment() { counter++; }
}

Is equivallent to

class Process{
     public void increment() { 
           synchronized(Process.class){
                  counter++; 
            }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Ehm, you wanna tell me that the compiler creates all the class member functions for each object created..? (Kinda new to java, developed in cpp before)
@Rouki Sorry for the confusion let me word that better.
Ok.. starting to get it I think. so when I declare this method as static (means it has no THIS now) what will the "Synchronized(this)" will look like now?
@Rouki updated. So since there is always one Process.class instance ever, the lock will block any number of instances that are trying to increment.
1

You may want to replace your int counter with an AtomicInteger counter - this way you can remove the synchronized keyword from the method, and it shouldn't matter if the method is a static or instance method.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.