Rouki
Rouki

Reputation: 2345

Basic multi-threading issue

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

Upvotes: 1

Views: 79

Answers (2)

John Vint
John Vint

Reputation: 40256

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

Upvotes: 7

Zim-Zam O&#39;Pootertoot
Zim-Zam O&#39;Pootertoot

Reputation: 18148

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.

Upvotes: 1

Related Questions