简体   繁体   English

同步方法和块之间有什么区别?

[英]What is the difference between synchronized methods and blocks?

What is the difference between synchronized methods and synchronized statements ? synchronized 方法synchronized 语句之间有什么区别?

If possible, please use an example to make it more clear. 如果可能,请使用示例使其更清晰。

A synchronized method locks the monitor associated with the instance of the class (ie 'this') or the class (if a static method) and prevents others from doing so until the return from the method. synchronized方法锁定与类实例(即'this')或类(如果是静态方法)关联的监视器,并阻止其他人这样做,直到从方法返回。 A synchronized block can lock any monitor (you tell it which) and can have a scope smaller than that of the encolsing method. 同步块可以锁定任何监视器(您告诉它哪个)并且可以使范围小于加载方法的范围。

Synchronized blocks are prefered if they don't end up equivalent to the entire scope of the method and/or if they lock something less draconian than the instance (or class if static). 如果同步块最终不等同于方法的整个范围和/或它们锁定的东西比实例(或静态的类)更严格,则优先使用同步块。

Quotes from the JLS (including example): 来自JLS的报价(包括示例):

JLS 14.19 The synchronized Statement JLS 14.19 synchronized语句

A synchronized statement acquires a mutual-exclusion lock on behalf of the executing thread, executes a block, then releases the lock. synchronized语句代表执行线程获取互斥锁,执行块,然后释放锁。 While the executing thread owns the lock, no other thread may acquire the lock. 当执行线程拥有锁时,没有其他线程可以获取锁。

JLS 8.4.3.6 synchronized Methods JLS 8.4.3.6 synchronized方法

A synchronized method acquires a monitor before it executes. synchronized方法在执行之前获取监视器。 For a class ( static ) method, the monitor associated with the Class object for the method's class is used. 对于类( static )方法,使用与方法类的Class对象关联的监视器。 For an instance method, the monitor associated with this (the object for which the method was invoked) is used. 对于实例方法,使用与this关联的监视器(调用该方法的对象)。

These are the same locks that can be used by the synchronized statement; 这些是synchronized语句可以使用的相同锁; thus, the code: 因此,代码:

 class Test { int count; synchronized void bump() { count++; } static int classCount; static synchronized void classBump() { classCount++; } } 

has exactly the same effect as: 具有与以下完全相同的效果:

 class BumpTest { int count; void bump() { synchronized (this) { count++; } } static int classCount; static void classBump() { try { synchronized (Class.forName("BumpTest")) { classCount++; } } catch (ClassNotFoundException e) { ... } } } 

So how are they different? 那他们有什么不同?

A quotes from Effective Java 2nd Edition , Item 67: Avoid excessive synchronization: 引用来自Effective Java 2nd Edition ,第67项:避免过度同步:

As a rule, you should do as little work as possible inside synchronized regions. 通常,您应该在synchronized区域内尽可能少地工作。

The synchronized modifier for methods, being a syntactic sugar that it is, is applicable in many but not all scenarios. 方法的synchronized修饰符(它是一种语法糖)适用于许多但不是所有场景。 The book goes to discuss in much deeper detail why you should avoid excessive synchronization, but basically by using synchronized statements, you have much greater control over the boundaries of your synchronized regions (and if the scenario requires it, you can also choose your own locks). 本书将更详细地讨论为什么你应该避免过度同步,但基本上通过使用synchronized语句,你可以更好地控制synchronized区域的边界(如果场景需要它,你也可以选择你自己的锁)。

Unless your method is very simple and/or you need to acquire the this lock for the entire duration of the method (or the Class object lock if the method is static ), you should use synchronized statements to limit the synchronization within the method to only to when you need it (ie when you're accessing shared mutable data). 除非您的方法非常简单和/或您需要在方法的整个持续时间内获取this锁(如果方法是static ,则需要Class对象锁),您应该使用synchronized语句将方法内的同步限制为仅到你需要的时候(即当你访问共享的可变数据时)。

A synchronized method is a method whose body is encapsulated automatically in a synchronized block. synchronized方法是一种方法,其主体自动封装在synchronized块中。

Thus, this is equal: 因此,这是平等的:

public void foo()
{
    synchronized (this)
    {
        bar();
    }
}

public synchronized void foo()
{
    bar();
}

synchronized on method is locked on a this object. synchronized方法上的synchronized被锁定在this对象上。 It's equals to synchronized (this) {} 它等于synchronized (this) {}

Standard synchronized is locked on specified object/monitor. 标准synchronized锁定在指定的对象/监视器上。 With synchronized (***) {} you can choose an object to use for locking. 使用synchronized (***) {}您可以选择用于锁定的对象。

A synchronized method is one where you have, in effect, placed the entire body of the function in a synchronized block. 实现的同步方法是将函数的整个主体放在同步块中。 A synchronized block has the advantage that you can apply the synchronized block to just a few select statements in the function, instead of to the function as a whole. 同步块的优点是,您可以将synchronized块应用于函数中的几个select语句,而不是作为整体的函数。 In general, it is best to make synchronized blocks as short as possible, since time spent in synchronized blocks is time that some other thread might be prevented from doing meaningful work. 通常,最好使同步块尽可能短,因为在同步块中花费的时间是一些其他线程可能无法进行有意义的工作的时间。 Another distinction is that you can specify a particular object on which to apply the lock when using a synchronized block whereas with a synchronized method, the object, itself is automatically used as the lock on which synchronization is performed. 另一个区别是,您可以在使用synchronized块时指定要应用锁定的特定对象,而使用synchronized方法时,对象本身会自动用作执行同步的锁定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM