有人能告诉我同步方法比同步块的优势与一个例子吗?
当前回答
来自Java规范摘要: http://www.cs.cornell.edu/andru/javaspec/17.doc.html
The synchronized statement (§14.17) computes a reference to an object; it then attempts to perform a lock action on that object and does not proceed further until the lock action has successfully completed. ... A synchronized method (§8.4.3.5) automatically performs a lock action when it is invoked; its body is not executed until the lock action has successfully completed. If the method is an instance method, it locks the lock associated with the instance for which it was invoked (that is, the object that will be known as this during execution of the body of the method). If the method is static, it locks the lock associated with the Class object that represents the class in which the method is defined. ...
基于这些描述,我想说以前的大多数答案都是正确的,同步方法可能对静态方法特别有用,否则您必须弄清楚如何获得“表示定义方法的类的Class对象”。
编辑:我原本以为这些是对实际Java规范的引用。澄清一下,本页只是对规范的总结/解释
其他回答
As already said here synchronized block can use user-defined variable as lock object, when synchronized function uses only "this". And of course you can manipulate with areas of your function which should be synchronized. But everyone says that no difference between synchronized function and block which covers whole function using "this" as lock object. That is not true, difference is in byte code which will be generated in both situations. In case of synchronized block usage should be allocated local variable which holds reference to "this". And as result we will have a little bit larger size for function (not relevant if you have only few number of functions).
你可以在这里找到更详细的解释: http://www.artima.com/insidejvm/ed2/threadsynchP.html
通常在方法级别上使用锁是不礼貌的。为什么要通过锁定整个方法来锁定一段不能访问任何共享资源的代码呢?因为每个对象都有一个锁,所以可以创建虚拟对象来实现块级同步。 块级的效率更高,因为它不锁定整个方法。
这里有一些例子
方法级
class MethodLevel {
//shared among threads
SharedResource x, y ;
public void synchronized method1() {
//multiple threads can't access
}
public void synchronized method2() {
//multiple threads can't access
}
public void method3() {
//not synchronized
//multiple threads can access
}
}
块级别
class BlockLevel {
//shared among threads
SharedResource x, y ;
//dummy objects for locking
Object xLock = new Object();
Object yLock = new Object();
public void method1() {
synchronized(xLock){
//access x here. thread safe
}
//do something here but don't use SharedResource x, y
// because will not be thread-safe
synchronized(xLock) {
synchronized(yLock) {
//access x,y here. thread safe
}
}
//do something here but don't use SharedResource x, y
//because will not be thread-safe
}//end of method1
}
(编辑)
对于像Vector和Hashtable这样的集合,当ArrayList或HashMap不同步时,它们是同步的,你需要设置synchronized关键字或调用Collections synchronized方法:
Map myMap = Collections.synchronizedMap (myMap); // single lock for the entire map
List myList = Collections.synchronizedList (myList); // single lock for the entire list
注意:静态同步方法和块工作在Class对象上。
public class MyClass {
// locks MyClass.class
public static synchronized void foo() {
// do something
}
// similar
public static void foo() {
synchronized(MyClass.class) {
// do something
}
}
}
In general these are mostly the same other than being explicit about the object's monitor that's being used vs the implicit this object. One downside of synchronized methods that I think is sometimes overlooked is that in using the "this" reference to synchronize on you are leaving open the possibility of external objects locking on the same object. That can be a very subtle bug if you run into it. Synchronizing on an internal explicit Object or other existing field can avoid this issue, completely encapsulating the synchronization.
同步的方法
优点:
您的IDE可以指示同步方法。 语法更加紧凑。 强制将同步块分割为单独的方法。
缺点:
与此同步,因此外部人员也可以与之同步。 将代码移到同步块之外更加困难。
同步块
优点:
允许为锁使用私有变量,从而将锁强制留在类内部。 同步块可以通过搜索变量的引用来找到。
缺点:
语法更复杂,因此使代码更难阅读。
就我个人而言,我更喜欢使用同步方法,类只关注需要同步的东西。这样的类应该尽可能小,所以应该很容易检查同步。其他人不需要关心同步。
推荐文章
- 如何分割逗号分隔的字符串?
- Java字符串—查看字符串是否只包含数字而不包含字母
- Mockito.any()传递带有泛型的接口
- 在IntelliJ 10.5中运行测试时,出现“NoSuchMethodError: org.hamcrest. matcher . descripbemismatch”
- 使用String.split()和多个分隔符
- Java数组有最大大小吗?
- 在Android中将字符串转换为Uri
- 从JSON生成Java类?
- 为什么java.util.Set没有get(int index)?
- Swing和AWT的区别是什么?
- 为什么Java流是一次性的?
- 四舍五入BigDecimal *总是*有两位小数点后
- 设计模式:工厂vs工厂方法vs抽象工厂
- Java:检查enum是否包含给定的字符串?
- 它的意思是:序列化类没有声明一个静态的最终serialVersionUID字段?