8 java concurrency multithreading synchronization
synchronized 方法和synchronized 陈述有什么区别?
如果可能,请使用示例使其更清晰.
sgo*_*les 13
synchronized方法锁定与类实例(即'this')或类(如果是静态方法)关联的监视器,并阻止其他人这样做,直到从方法返回.同步块可以锁定任何监视器(您告诉它哪个)并且可以使范围小于加载方法的范围.
如果同步块最终不等同于方法的整个范围和/或它们锁定的东西比实例(或静态的类)更严格,则优先使用同步块.
来自JLS的报价(包括示例):
synchronized声明一个
synchronized说法获得代表执行线程的互斥锁,执行一个块,然后释放锁.当执行线程拥有锁时,没有其他线程可以获取锁.
synchronized方法甲
synchronized方法获取监视器它执行之前.对于class(static)方法,使用与Class方法类的对象关联的监视器.对于实例方法,使用与this(调用该方法的对象)关联的监视器.这些是
synchronized语句可以使用的相同锁; 因此,代码:Run Code Online (Sandbox Code Playgroud)class Test { int count; synchronized void bump() { count++; } static int classCount; static synchronized void classBump() { classCount++; } }具有与以下完全相同的效果:
Run Code Online (Sandbox Code Playgroud)class BumpTest { int count; void bump() { synchronized (this) { count++; } } static int classCount; static void classBump() { try { synchronized (Class.forName("BumpTest")) { classCount++; } } catch (ClassNotFoundException e) { ... } } }
那他们有什么不同?
引用来自Effective Java 2nd Edition,第67项:避免过度同步:
通常,您应该在
synchronized区域内尽可能少地工作.
synchronized方法的修饰符,它是一种语法糖,适用于许多但不是所有场景.本书将更详细地讨论为什么要避免过度同步,但基本上通过使用synchronized语句,您可以更好地控制synchronized区域的边界(如果场景需要它,您也可以选择自己的锁).
除非您的方法非常简单和/或您需要this在方法的整个持续时间内获取锁(或者Class如果方法是对象锁static),您应该使用synchronized语句将方法内的同步限制为仅在您需要时它(即当你访问共享的可变数据时).