2012-08-06 90 views
1

我有一个简单的问题:爪哇 - 执行方法只有一次

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

任何建议非常感谢。

+3

为什么不使用标志,你第一次设置为false? – thegrinner 2012-08-06 13:04:45

+3

您可以实现例如给方法增加一个参数,但这不是更多的设计问题吗?你想要建模什么? – twoflower 2012-08-06 13:05:45

+0

根据编码准则,这将被视为循环依赖性,应该避免。既然你问了,我们可以在A类中维护一个静态布尔类型,它只控制一次类A中doSth的执行。 – sundar 2012-08-06 13:06:35

回答

7

添加的状态标志类:

​​

使用volatile如果多个线程在起作用。

+0

也许你想清除标志,否则'doSth'永远不会再被调用。否则,你可以清除'b = null;'并检查是否为空。 – 2012-08-06 13:20:11

+0

不应在实际并发情况下使用此示例。你可以让两个线程运行“if”,并且都会传递到下一行。 这是更好地在这里使用CAS,是这样的:

 private final AtomicBoolean called = new AtomicBoolean(); and then if (!called.compareAndSet(false, true)) return; 
或者如果你喜欢使用“简单和纯洁”的风格,可以使用双带同步检查:
 boolean mayPass = false; if (!called) { synchronized(this) { // or some external object if (!called) { called = true; mayPass = true; } } } if (!mayPass) return; ... 
dchekmarev 2013-12-12 17:16:30

+0

@dchekmarev你说得对!我不能相信我省略了同步......(使方法同步 - 对于这个例子足够好) – Bohemian 2013-12-13 00:18:08

2

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

Class A{ 
    boolean isModified = false; 
    B b; 

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

不起作用..你必须改变isModified第一 – Razvan 2012-08-06 13:06:14

+0

是的,我纠正它,谢谢。 – Autar 2012-08-06 13:06:53

1

添加boolean alreadyExecuted A类和修改doSmth()的实施

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

    } 
} 
2

我会尝试寻找不涉及循环依赖的解决方案。 A和B真的必须引用彼此吗?在更高的层面上,你想要达到什么目标?你可以使用A和B对象发布一些客户端代码吗?

1

认为这是一个黑客...

使用boolean变量

Class A{ 

    B b; 
    public isOk = true; 

    public void doSth{ 

     if (isOk){ 

     b.modify(); 
     isOk = false; 

     } 

} 
1

也许你应该改变设计不递归调用的方法,或者如果你不能只是添加参数,以此来doSth方法

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

把你的工作在构造函数中

Class A{ 

    B b; 

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

} 
1

这是“最佳”示例的修补程序,因此无法在并发/多线程情况下真正使用它。你可以让两个线程运行“if”,并且都会传递到下一行。 这是更好地在这里使用CAS,是这样的:

 
private final AtomicBoolean called = new AtomicBoolean(); 

and then 

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

,或者如果你喜欢使用“简单和纯洁”的风格,采用双重检查与同步:

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