Java 跨类同步

Java 跨类同步,java,multithreading,synchronization,synchronized,critical-section,Java,Multithreading,Synchronization,Synchronized,Critical Section,我有两个线程同时运行,一个主线程和一个实现Runnable的侦听器 主线程和侦听器都有一个关键部分,特别是在主线程中运行的管理器类中的方法getObjectList(String),以及在侦听器线程中运行的方法handleNewObjects(String,List) 我当前的计划是使getObjectList()成为一个同步方法: class Manager { protected synchronized getObjectList() { // Do critic

我有两个线程同时运行,一个主线程和一个实现
Runnable
的侦听器

主线程和侦听器都有一个关键部分,特别是在主线程中运行的管理器类中的方法
getObjectList(String)
,以及在侦听器线程中运行的方法
handleNewObjects(String,List)

我当前的计划是使
getObjectList()
成为一个同步方法:

class Manager {

    protected synchronized getObjectList() {
        // Do critical section stuff
    }
}
并使
handleNewObjects()
如下所示

class Listener implements Runnable {
    private final Manager myManager;

    handleNewObjects() {
        synchronized (myManager) {
            // Do critical section stuff
        }
    }
}
这会确保我的关键部分不会同时运行吗?
我应该以其他方式同步吗

这会确保我的关键部分永远不会同时运行吗

是的,但正如奎利昂所指出的,确保它们是同一个对象。如果您正在使用任何框架,请注意框架创建的代理

我应该以其他方式同步吗

生产者-消费者设置非常常见。当你有每一个的倍数时,事情变得更加棘手。与其自己重新发明它,不如看一看一些正在开发的类。从Javadocs(不完全是您正在做的,但很接近):

如果
getObjectList()
是一个同步方法,并且
Listener
中的
myManager
与将修改共享对象集的实例是同一个
Manager
实例,则可以

如果不知道现有代码之间的关系,就很难说是否有更好的解决方案适合您,但是这种方法可能会被视为有点脆弱。更改对象
管理器
锁定将导致
侦听器
不再是线程安全的,如果两个关键部分修改的共享对象已经存在于管理器中,您还可以让侦听器在管理器中调用另一个同步对象,例如
myManager.handleNewObjects()

我所说的对象管理器锁定的更改是指如果管理器从:

protected synchronized getObjectList() {
    // Do critical section stuff
}


那么监听器就不再是线程安全的,因为它不再在同一个对象上锁定它的关键部分。

假设getObjectsList是一种无更新的检索方法,您可以利用ReadWriteLocks改进并发性。这里handle*方法是更新基础列表的方法。请参阅:

你所说的“更改对象管理器锁定的对象”是什么意思?@Stephan需要代码来解释我的意思,所以我修改了答案show@NESPowerGlove提出了一个很好的观点。基本上,它归结为封装同步逻辑或将其分散到几个类中。当它展开时,参与同步操作的任何类中的细微更改都可能导致中断。最好把它封装起来。可能按照Khanna111的建议使用ReadWriteLock,或者使用BlockingQueue。
protected synchronized getObjectList() {
    // Do critical section stuff
}
protected getObjectList() {
    synchronized (myPrivateFinalLockObject) {
        // Do critical section stuff
    }
}
protected getObjectList() {
    delegatingWorkToSomeOtherThreadSafeObject.getObjectList();
}