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?
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()
.