Java - 只执行一次方法

时间:2012-08-06 13:02:01

标签: java recursion infinite-loop

我有一个简单的问题:

Class A{

    B b;

    public void doSth{ 
         //This method should execute only once
         b.modify(); //calls doSth() again...
    }
}

程序运行时,A的实例传递给B,B调用doSth(例如作为回调)。 b.modify让B再次呼叫A.doSth(),这将是无限的呼叫序列。我想要实现的是:我想执行一次doSth(),修改B,然后在下次执行时以某种方式停止无限调用链并且不执行b.modify

任何建议都非常感谢。

8 个答案:

答案 0 :(得分:7)

向您的班级添加州旗:

Class A {

    B b;
    private volatile boolean called;

    public synchronized void doSth { 
         if (called) return;
         called = true;
         b.modify();
    }
}

如果正在播放多个主题,请使用volatile

答案 1 :(得分:2)

您可以拥有一个布尔字段,并在第一次调用该方法时将其设置为true。

Class A{
    boolean isModified = false;
    B b;

    public void doSth{ 
        if(!isModified) {
            this.isModified = true;
            b.modify();
        }
    }
}

答案 2 :(得分:2)

我试图找到一个不涉及循环依赖的解决方案。 A和B真的要互相参考吗?在更高的层面上,你想要实现什么?你能用A和B对象发布一些客户端代码吗?

答案 3 :(得分:1)

向A类添加boolean alreadyExecuted并将doSmth()的实现修改为

 public void doSth{ 
     if(!alreadyExecuted){
         alreadyExecuted = true; 
         b.modify(); 

     }
}

答案 4 :(得分:1)

将此视为黑客...

使用boolean变量

Class A{

    B b;
    public isOk = true;

    public void doSth{ 

        if (isOk){

         b.modify(); 
         isOk = false;

        }

}

答案 5 :(得分:1)

也许你应该改变设计,不要递归地调用这些方法,或者你不能只是在你的doSth方法中添加参数

doSth(boolean modify)
 {
  if (modify) 
  {
    b.modify();
  }
  ...
 }

答案 6 :(得分:1)

这是对“最佳”示例的修复,因为没有人应该在并发/多线程情况下使用它。您可以让两个线程都运行“if”,并且两个线程都将传递到下一行。 最好在这里使用CAS,例如:

private final AtomicBoolean called = new AtomicBoolean();

and then

if (!called.compareAndSet(false, true)) return;

或者如果您更喜欢使用“普通和纯粹”样式,请使用带有synchronized的双重检查:

private volatile boolean called;

and then

boolean mayPass = false;
if (!called) {
  synchronized(this) { // or some external object
    if (!called) {
      called = true;
      mayPass = true;
    }
  }
}
if (!mayPass) return;
...

答案 7 :(得分:0)

将你的工作放在构造函数中

Class A{

   B b;

   A(){
       //This should execute only once
       b.modify(); //calls doSth() again...
   }

}