Java方法线程安全

3

我有一个场景,搜索了很多次,但没有得到令人满意的答案。

有一个服务类,名为WebserviceInvokerService,

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

callBackFun ==> 是当某个事件发生时调用的函数。

在 callBackFun 中,我会检查数据库并相应地进行服务调用(类的任何实例成员都不参与此过程)。

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

我希望 callBackFun 在对象间“同步”调用。那么,对于 callBackFun 的“同步”在这种情况下是否有意义?


每当一个对象的可变状态被2个或更多线程共享时,您必须进行同步。由于您没有向我们展示或告诉我们要保护的状态,因此无法回答您的问题。 - scottb
如果您想在对象之间进行同步,应该在callBackFun方法内使用synchronized(WebserviceInvokerService.class){...}。 - Paulo
听起来你好像是在不真正理解的情况下添加了synchronized。这个方法改变的可变状态是什么,使它成为线程不安全的? - Kayaman
3个回答

2

为了在多个实例之间同步,您应该使用带有静态引用的 synchronized。

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

1
与其在类对象本身上进行同步,使用“private static final”变量可能更好。类对象在整个应用程序中都是可访问的,应用程序的其他部分可能会为其他不相关的目的在其上进行同步,这些目的不应与类自身的内部自我同步相互作用。 - Wyzard
正如@Lµk4s的回答中所提到的 - Gokul Kulkarni

2

如果您有多个WebserviceInvokerServices实例,方法在每个实例中将同步,但不会跨实例同步。

您可能正在寻找的是锁。

您可以尝试以下内容:

private final static Lock lock = new ReentrantLock();

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

编辑: 按照@Wyzard提到的建议,添加了final关键字。


4
这个锁应该几乎肯定声明为“final”,因为你不想在程序运行时用不同的锁替换它。 - Wyzard

-1

由于callBackFun不使用实例成员(根据帖子:类的任何实例成员都没有涉及到这个业务)

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

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接