Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 同步方法与同步块_Java_Concurrency - Fatal编程技术网

Java 同步方法与同步块

Java 同步方法与同步块,java,concurrency,Java,Concurrency,如果我有以下代码 class SomeClass { ... public synchronized methodA() { .... } public synchronized methodB(){ .... } } 这将在“This”对象上同步。 但是,如果我这里的主要目标是确保多个线程不同时使用methodA(或methodB),但它们可以同时使用methodA和methodB, 那么这种设计有限制吗?因为这里thread1锁定对象(与对象关联的监控对象)以运行methodA,

如果我有以下代码

class SomeClass {    
...
public synchronized methodA() {
....
}

public synchronized methodB(){
....
}
}
这将在“This”对象上同步。
但是,如果我这里的主要目标是确保多个线程不同时使用methodA(或methodB),但它们可以同时使用methodA和methodB,
那么这种设计有限制吗?因为这里thread1锁定对象(与对象关联的监控对象)以运行methodA,但同时thread2也在等待对象锁定,即使methodA和methodB可以同时运行。
这种理解正确吗

如果是,这是一种在私有虚拟对象上使用同步块的情况,这样methodA和methodB可以与不同的线程并行运行,而不是methodA(或methodB)与不同的线程并行运行。

谢谢

您自己已经回答了这个问题:每个方法使用一个锁对象,您就安全了

private final Object lockA = new Object();
private final Object lockB = new Object();
public void methodA() {
    synchronized(lockA){
        ....
    }
}
public void methodB() {
    synchronized(lockB){
        ....
    }
}

对于更高级的锁定机制(例如),Brian Goetz等人阅读。您还应该阅读,它还包含一些关于使用
同步的
的项目,如果您想允许运行
methodA()
methodB()
同时执行,但如果将每个方法限制为一个线程,则需要两个单独的对象进行同步。例如:

class SomeClass {
    private final Object lockA = new Object();
    private final Object lockB = new Object();

    public void methodA() {
        synchronized (lockA) {
            // 
        }
    }

    public void methodB() {
        synchronized (lockB) {
            // 
        }
    }
}

如果我的理解是正确的,您希望允许线程T1在线程T2运行methodB()的同时运行methodA()——但您不希望线程T1在线程T2运行methodA()的同时运行methodA()(和methodB相同),对吗?
对于这个场景,您不能只使用一个简单的同步方法——相反,正如您所说,您将需要两个虚拟对象(一个用于methodA,一个用于methodB)来同步。或者你可以使用新的锁类——每个方法一个锁实例。

这里回答:-请使用搜索函数,另一个问题甚至有完全相同的名称并涵盖相同的问题。我认为你是对的,但一个问题是静态方法的锁不同于普通对象方法的锁。文档非常适合这方面的内容:将
lockA
lockB
作为
final
字段。然后您可以使用上面显示的方法之一,或者如我所说,查看java.util.concurrent.locks.ReentrantLock。