user710818
user710818

Reputation: 24288

How provide in java atomic read/write of 2 variables together?

In my class I have code like:

int counter1;
int counter2;

public void method1(){
 if (counter1>0) {
  ...........do something
   if (counter2>0) {
    ....do something else
    }
}

public void method2() {
  counter1=0;
  counter2=0;
}

I need that both counters set together. I am afraid that OS can to method1 can be invoked after setting counter1 only. Does it possible? Thanks.

Upvotes: 4

Views: 1133

Answers (3)

Leonard Brünings
Leonard Brünings

Reputation: 13282

Either use the synchronized keyword as the other answer suggest or use the ReentrantReadWriteLock if you have more reads than writes to the counter, for better performance. You can read about the lock here http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html

private int counter1;
private int counter2;
private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private final Lock r = rwl.readLock();
private final Lock w = rwl.writeLock();

public void method1(){
   r.lock();
   try { 
     if (counter1>0) {
        ...........do something
     if (counter2>0) {
        ....do something else
     }
   } finally { r.unlock(); }

}

public void method2() {
  w.lock();
  try { 
    counter1=0;
    counter2=0; 
  } finally { w.unlock(); }

}

Upvotes: 4

cdc
cdc

Reputation: 2571

Use a synchronized block or method to wrap access to the two counters, remember to use the same object to lock on.

Upvotes: 1

Sean Reilly
Sean Reilly

Reputation: 21836

Sure, just use the synchronized keyword:

private final Object LOCK = new Object();
int counter1;
int counter2;

public void method1() {
  synchronized(LOCK) {
     if (counter1>0) {
      ...........do something
       if (counter2>0) {
        ....do something else
       }
    }
}
public void method2() {
  synchronized(LOCK) {
    counter1=0;
    counter2=0;
  }
}

Some tips:

Use a private object for synchronization rather than marking a method synchronized. This prevents something external to you class from grabbing the lock and stalling things.

Make sure that you use the synchronized keyword everywhere, and make sure you always synchronize on the same object. If you forget to do either of those things, two processes can access the fields at the same time.

Beware of deadlocks. In a perfect world you'd write unit tests to ensure that locking is working the way you think it is.

Upvotes: 3

Related Questions