0

I am trying to synchronize a int counter between few threads (6). Below is my worker class. I am trying to synchronize my private field countertest:

public class DbWorker implements Callable {

    private final Object lock = new Object();
    private int countertest = 0 ;

    private  boolean  IsActive(Integer act)
    {
        synchronized(lock){ 
        boolean exists = false;
        countertest++;
            ....
       System.out.println("countertest  IS :  " + countertest );
         }
       return true;
    }

     public void run() {
        ....
        IsActive(act):
        ...
     }

}

In my main class I am creating threads using for loop and ExecutorService. Please see below:

private ExecutorCompletionService<Integer> _objQueue ;

 for(int j = 0; j < 6; j++){
     _objQueue.submit( new DbWorker( "SOME PARAMETER" , _snapshots.get(j) , j )    );
}

My countertest variable is not synced it is printing different number (non-sequential). What am I doing wrong?

Nayuki
  • 17,911
  • 6
  • 53
  • 80
Kenner Dev
  • 327
  • 1
  • 4
  • 13
  • The "duplicate", IMO, is a bad question with a bad answer. Bad because it promotes the idea that objects can be `static` or not static. (They can't: Only _variables_ can be `static` or not static.) And, bad because it promotes the idea that `static` makes a difference in locking. (It doesn't. What matters is, two threads can not lock the same object at the same time. Whether the `synchronized` statement obtains the reference from a static variable, from a non-static variable, or by calling a method is irrelevant.) – Solomon Slow Oct 16 '15 at 13:08

2 Answers2

3

Your lock

private final Object lock = new Object();

is an instance field. In other words, there's one per DbWorker object.

You then submit DbWorker instances to for execution

_objQueue.submit( new DbWorker( "SOME PARAMETER" , _snapshots.get(j) , j )    );

Each thread has its own DbWorker and therefore its own lock. Threads are never contending with any other thread.

Create one DbWorker and share it among threads, ie. submit the same DbWorker instance every time.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
2

Because you creating an instance in the loop where where countertest and lock are instance variable and hence every object will get a new one.

  1. countertest will always be 1 in this case, it is not shared between instances

  2. multiple threads aren't acquiring the same lock, so it is useless.

Nayuki
  • 17,911
  • 6
  • 53
  • 80
Sleiman Jneidi
  • 22,907
  • 14
  • 56
  • 77