有人能告诉我同步方法比同步块的优势与一个例子吗?
当前回答
在同步方法的情况下,锁将在对象上获得。但是如果你使用同步块,你可以选择指定一个对象来获取锁。
例子:
Class Example {
String test = "abc";
// lock will be acquired on String test object.
synchronized (test) {
// do something
}
lock will be acquired on Example Object
public synchronized void testMethod() {
// do some thing
}
}
其他回答
同步的方法
优点:
您的IDE可以指示同步方法。 语法更加紧凑。 强制将同步块分割为单独的方法。
缺点:
与此同步,因此外部人员也可以与之同步。 将代码移到同步块之外更加困难。
同步块
优点:
允许为锁使用私有变量,从而将锁强制留在类内部。 同步块可以通过搜索变量的引用来找到。
缺点:
语法更复杂,因此使代码更难阅读。
就我个人而言,我更喜欢使用同步方法,类只关注需要同步的东西。这样的类应该尽可能小,所以应该很容易检查同步。其他人不需要关心同步。
主要的区别是,如果你使用同步块,你可以锁定一个对象,而不是这个,这允许更灵活。
假设您有一个消息队列和多个消息生产者和消费者。我们不希望生产者相互干扰,但是消费者应该能够检索消息,而不必等待生产者。 我们只需要创建一个对象
Object writeLock = new Object();
从现在开始,每当制作人想要添加一条新信息时,我们就会锁定它:
synchronized(writeLock){
// do something
}
因此,消费者可能仍会阅读,而生产者将被锁定。
谁能告诉我同步方法比同步块的优势与一个例子?谢谢。
与块相比,使用同步方法并没有明显的优势。
也许唯一的一点(但我不认为这是优点)是您不需要包含对象引用this。
方法:
public synchronized void method() { // blocks "this" from here....
...
...
...
} // to here
布洛克:
public void method() {
synchronized( this ) { // blocks "this" from here ....
....
....
....
} // to here...
}
看到了吗?一点好处都没有。
块确实比方法有优势,主要是灵活性,因为你可以使用另一个对象作为锁,而同步方法将锁定整个对象。
比较:
// locks the whole object
...
private synchronized void someInputRelatedWork() {
...
}
private synchronized void someOutputRelatedWork() {
...
}
vs.
// Using specific locks
Object inputLock = new Object();
Object outputLock = new Object();
private void someInputRelatedWork() {
synchronized(inputLock) {
...
}
}
private void someOutputRelatedWork() {
synchronized(outputLock) {
...
}
}
另外,如果方法增长了,你仍然可以保持同步段的分离:
private void method() {
... code here
... code here
... code here
synchronized( lock ) {
... very few lines of code here
}
... code here
... code here
... code here
... code here
}
同步方法可以使用反射API进行检查。这对于测试某些契约很有用,比如模型中的所有方法都是同步的。
下面的代码段打印哈希表的所有同步方法:
for (Method m : Hashtable.class.getMethods()) {
if (Modifier.isSynchronized(m.getModifiers())) {
System.out.println(m);
}
}
Synchronized方法用于锁定所有对象 同步块用于锁定特定对象
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 自动化invokerrequired代码模式
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder