4

在我的课堂上,我有如下代码:

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

我需要将两个计数器设置在一起。恐怕只有在设置 counter1 后才能调用 OS 到 method1。有可能吗?谢谢。

4

3 回答 3

4

如果您对计数器的读取次数多于写入次数,则可以使用 synchronized 关键字作为其他答案的建议,或者使用 ReentrantReadWriteLock 以获得更好的性能。您可以在此处阅读有关锁的信息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(); }

}
于 2012-02-10T10:08:07.783 回答
3

当然,只需使用synchronized关键字:

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

一些技巧:

使用私有对象进行同步,而不是将方法标记为同步。这可以防止你类外部的东西抓住锁和拖延东西。

确保在任何地方都使用 synchronized 关键字,并确保始终在同一个对象上同步。如果您忘记执行其中任何一项操作,则两个进程可以同时访问这些字段。

谨防死锁。在一个完美的世界中,您将编写单元测试以确保锁定以您认为的方式工作。

于 2012-02-10T10:00:36.697 回答
1

使用同步块或方法来包装对两个计数器的访问,记住使用相同的对象来锁定。

于 2012-02-10T10:07:45.693 回答