[英]Which is more efficient and why?
在以下两个同步策略中,哪一个被优化(如在处理和生成的字节代码中)以及应该使用其中一个的场景。
public synchronized void addName(String name)
{
lastName = name;
nameCount++;
nameList.add(name);
}
要么
public void addName(String name) {
synchronized(this) {
lastName = name;
nameCount++;
nameList.add(name);
}
}
还有什么是处理并发的可行方法:
java.util.concurrent
包 Job
或UIJob
API(如果在eclipse PDE环境中工作) 谢谢
java.util.concurrent
非常适合尽可能使用同步原语,因为它允许您在更高的抽象级别工作,并使用由技术娴熟的人员编写并密集测试的代码。 哪一个被优化(如在处理和生成的字节代码中)
根据这篇IBM DeveloperWorks文章第1节 ,与synchronized块相比, synchronized方法生成的字节码更少 。 这篇文章解释了原因。
文章摘录:
当JVM执行synchronized方法时,执行线程识别方法的method_info结构设置了ACC_SYNCHRONIZED标志,然后它自动获取对象的锁,调用方法并释放锁。 如果发生异常,则线程会自动释放锁。
另一方面,同步方法块绕过JVM内置的对获取对象锁和异常处理的支持,并要求以字节代码显式写入功能。 如果您读取具有同步块的方法的字节代码,您将看到十几个额外的操作来管理此功能。 清单1显示了生成synchronized方法和synchronized块的调用:
编辑发表第一条评论
为了给其他SOers信用,这里有一个很好的讨论为什么人们会使用同步。 块。 如果你搜索一下,我相信你可以找到更多有趣的讨论:)
我个人没有必要使用同步。 块锁定在比其他另一个目的this
,但是这是一个使用SOers指出关于同步。 块。
从任何效率的角度来看,这都无关紧要。
拥有块的重点是你可以指定自己的锁。 您可以选择封装在对象中的锁,而不是使用this
锁,结果是您可以更好地控制谁可以获取锁(因为您可以从对象外部无法访问该锁)。
如果你使用this
作为锁(无论你是在方法上放置同步还是使用块),程序中的任何东西都可以获得对象的锁定,并且更难以推断出你的程序正在做什么。
限制对锁的访问会使您获得可判断性的巨大收益,拥有这种确定性比在某处削减字节码更有利。
我知道这可能是一个例子,但是如果你打算编写这样的代码 - 再想一想。
对我而言,您看起来像是在复制信息,除非您发现需要对代码进行性能更改,否则不应该这样做。 (你几乎不应该这样做)。
如果你像现在这样做了什么,你还必须同步访问引用变量的所有地方,这将使代码的可读性和可维护性更低。
您可以删除所有锁定:
class Names {
AtomicReference<Node> names = new AtomicReference<Node>();
public void addName(final String name) {
Node old = names.get();
while (!names.compareAndSet(old, new Node(old, name))) {
old = names.get();
}
}
public String getName() {
final Node node = names.get();
return (node == null) ? null : node.name;
}
static class Node {
final Node parent;
final String name;
Node(final Node parent, final String name) {
this.parent = parent;
this.name = name;
}
int count() {
int count = 0;
Node p = parent;
while (p != null) {
count++;
p = p.parent;
}
return count;
}
}
}
这基本上是Treiber堆栈实现。 您可以获取大小,当前名称,并且可以轻松地在内容上实现迭代器(尽管与示例中的迭代器相反)。 根据您的需要,也可以使用备用的写时复制容器。
不可能说,因为这两个代码片段不相同。
差异(缺少调用add的同步)可能很重要,可能不是。 从你给我们的东西不可能说出来。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.