2016-10-23 169 views
3

我有一个场景,搜索了一下,但没有得到满意的答案。Java方法线程安全

有一服务类别,WebserviceInvokerService,

class WebserviceInvokerService { 
    @Override 
    public void synchronized callBackFun() {...} 
} 

callBackFun ==>是当一个事件(一些事件)时它获取调用的函数。

在callBackFun中,我检查数据库并相应地进行服务调用(此类业务中没有涉及该类的实例成员)。

我已经使callBackFun同步。有可能会创建WebserviceInvokerService的多个实例,并且会在这些对象上调用callBackFun。

我想callBackFun被称为“同步”跨对象。那么callBackFun的“同步”在这种情况下会有什么意义。

+0

只要对象的可变状态由2个或更多线程共享,就必须进行同步。既然你没有向我们展示或告诉我们你想要保护的状态,就不可能回答你的问题。 – scottb

+0

如果你想跨对象进行同步,你应该在callBackFun方法内部使用同步的(WebserviceInvokerService.class){...} – Paulo

+0

这听起来有点像你添加'synchronized'而没有真正理解原因。该方法改变的可变状态是什么使它不安全? – Kayaman

回答

2

如果您在java多个实例WebserviceInvokerServices的方法将在所有这些情况下同步,但不能跨越的实例。

你可能要找的是一个锁。

你可以试试这个:

private final static Lock lock = new ReentrantLock(); 

@Override 
public void callBackFun() { 
    lock.lock(); 
    try { 
     // Do things here 
    } finally { 
     lock.unlock(); 
    } 
} 

编辑: 加入由@Wyzard

+4

而且锁定几乎可以肯定地声明为'final',因为在程序运行时,您不希望用另一个锁来替换它。 – Wyzard

2

要跨实例进行同步,应该使用与静态引用同步。

class WebserviceInvokerService { 
    @Override 
    public void callBackFun() { 
     synchronized(WebserviceInvokerService.class) {... } 
    } 
} 
+1

不是在类对象本身上进行同步,而是使用'private static final'变量可能更好。类对象在整个应用程序中都是可访问的,并且应用程序的其他部分可能会与其他不相关的目的进行同步,这些目的不应与类自身的内部自同步进行交互。 – Wyzard

+0

正如@Lμk4s的答案中所提到的那样 –

-1

由于callBackFun提到不使用实例成员(按后最终关键字:类没有实例成员涉及此业务)

您可以将此代码放在static synchronized方法中,以便存在类级锁。从您的实例方法调用它

public synchronized void callBackFun() { 
    actualFunLogic(); 
} 

private static synchronized void actualFunLogic() 
{ 
    ..... 
}