javamultithreadingsynchronized-blockatomicinteger

AtomicInteger vs synchronized block


I have a problem where I need to synchronize access to array of integers in java. My code looks something like this.

   Class X {

         int[] counters = new int[100];

         Object lock = new Object ();

         void increment (int idx){
         synchronized (lock){
              ++counters[idx];
             }
          }

          void print(){ 
             StringBuffer buf = new StringBuffer ();
             synchronized (lock){
                   for( int i=0; i<100; i++;){
                     buf.append(",");
            buf.append(counters [i]);
                     } //End for
              }//End synchronized    
           System.out.println(buf.toString());
            } 
    }

Currently I am using single lock to synchronize access to array of integers. But I want to use one lock for each counter.

So I modified code to something like below.

    Class X {

     int[] counters = new int[100];

     Object[] locks = new Object[100];

     static{
          for(int i=0;i<100;i++){
               locks [i] = new Object ();
           }
       }

     void increment (int idx){
            synchronized (locks[idx]){
                ++counters[idx];
             }
       }

     void print(){ 
         StringBuffer buf = new StringBuffer ();
        for( int i=0; i<100; i++;){
                 buf.append(","); 
           synchronized (lock[i]){
                 buf.append(counters [i]);
            }//End synchronized
        } //End for
      System.out.println(buf.toString());
    } 
}

But my colleague suggested me to use AtomicInteger instead of synchronized blocks.

Does AtomicInteger has same effect as synchronized block?


Solution

  • Generally, AtomicInteger has not the same effect as synchronized block. But for simple tasks as yours, AtomicInteger can be used to get rid of synchronized blocks:

    AtomicInteger[] counters = new AtomicInteger[100];
    
    void increment (int idx){
        counters[idx].incrementAndGet();
    }
    
    void print(){ 
        StringBuffer buf = new StringBuffer ();
        for( int i=0; i<100; i++;){
             buf.append(","); 
             buf.append(counters[i].get);
        } //End for
        System.out.println(buf.toString());
    } 
    

    You need not any synchronization for print().