我写过几年的C ++。然后开始用Java编写。 Java中有synchronized语句。这对我来说是新的,我找到了以下用法:
synchronized (NetworkManager.class) {/*some code*/}
和
NetworkManager myInstance = new NetworkManager();
synchronized(myInstance){/*some code*/}
我知道synchronized语句将阻止对对象中同步部分的其他同步访问。但我对同步的论点感到困惑。
我认为如果我想阻止某些方法,那么我应该在C ++中同步 myInstance 以获得第二个例子。如果我创建另一个实例,它应该没有影响力。这是对的吗?
如果正确,使用NetworkManager.class
会发生什么? .class 会将类对象引用返回给NetworkManager
吗?它会在哪些情况下生效?或者它会影响所有NetworkManager
个实例吗?
答案 0 :(得分:3)
synchronized (NetworkManager.class) {//some code}
将获得Class object
NetworkManager
课程的锁定。如果您在访问这些方法时已在同一个类对象(Networkmanager.class)上同步,它将阻止 concicure 访问static fields and methods
类的Networkmanager
。
或
NetworkManager myInstance = new NetworkManager();
synchronized(myInstance){//some code}
在上面两行中,您将锁定NetworkManager类的特定实例(而不是类本身)。
答案 1 :(得分:2)
使用synchronized (object)
时,当前Thread
将获取所提供对象的监视器锁定(并在退出块或等待对象时释放它)。如果监视器锁已由另一个线程保持,则该线程将为该锁排队并等待它变为可用。换句话说,使用synchronized提供了object
作为互斥锁的独占访问权限。请注意,使用synchronized还可以提供某些内存可见性保证。
使用synchronized (myInstance)
时,锁定提供的实例。使用相同实例的所有同步块和此实例的synchronized
实例方法将使用相同的互斥锁。
当您使用synchronized (NetworkManager.class)
时,您锁定Class
NetworkManager
实例。使用NetworkManager.class
的所有同步块(假设它们都来自同一ClassLoader
}和static synchronized
NetworkManager
方法将使用相同的互斥锁。
因此使用synchronized (NetworkManager.class)
不会锁定所有实例。锁定实例或Class
对象之间唯一真正的区别是前者包含关于实例的同步方法的锁定,而后者包括关于同步静态的锁定班级方法;在所有其他方面,它们的工作方式相同:锁定提供的对象。
您可能还想阅读Java Concurrency tutorial。