在以下两个同步策略中,哪一个被优化(如在处理和生成的字节代码中)以及应该使用其中一个的场景。
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环境中工作)由于
答案 0 :(得分:5)
java.util.concurrent
非常适合尽可能使用同步原语,因为它允许您在更高的抽象级别工作,并使用由技术娴熟的人员编写并进行密集测试的代码。答案 1 :(得分:5)
哪一个被优化(如处理和生成的字节代码)
根据this IBM DeveloperWorks Article Section 1,与同步块相比, synchronized方法生成的字节码更少。这篇文章解释了原因。
文章摘录:
当JVM执行synchronized方法时,执行线程识别方法的method_info结构设置了ACC_SYNCHRONIZED标志,然后它自动获取对象的锁,调用方法并释放锁。如果发生异常,线程会自动释放锁。
同步方法块 另一方面,绕过了JVM 内置支持获取 对象的锁定和异常处理 并要求功能 用字节代码明确写出来。如果 你读取方法的字节代码 有了同步块,你会的 再看十几个 管理这个的操作 功能。清单1显示了调用 生成两个同步方法 和一个同步块:
已编辑以解决第一条评论
为了给其他SOers提供信用,这里有一个很好的讨论为什么会使用同步。块。如果您搜索一下,我相信您可以找到更有趣的讨论:)
Is there an advantage to use a Synchronized Method instead of a Synchronized Block?
我个人不必使用同步。阻止锁定除this
以外的另一个对象,但这是SOERS指出的关于同步的一个用法。块。
答案 2 :(得分:2)
从任何效率的角度来看,这都无关紧要。
拥有阻止的重点是你可以指定自己的锁。您可以选择封装在对象中的锁,而不是使用this
,结果是您可以更好地控制谁可以获取锁(因为您可以从对象外部无法访问该锁)。
如果您使用this
作为锁定(无论是对方法进行同步还是使用块),程序中的任何内容都可以获取对象的锁定,并且更难以推断出您的程序是在做。
限制对锁的访问会带来可判断性的巨大好处,拥有这种确定性比在某处削减字节码更有利。
答案 3 :(得分:1)
我知道这可能是一个例子,但如果你打算编写这样的代码 - 请再想一想。
对我而言,您似乎在复制信息,除非您发现需要对代码进行性能更改,否则不应该这样做。 (你几乎不应该这样做。)
如果你像现在这样做了,你还必须同步访问引用变量的所有地方,这将使代码的可读性和可维护性更低。
答案 4 :(得分:1)
您可以删除所有锁定:
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堆栈实现。您可以获取大小,当前名称,并且可以轻松地在内容上实现迭代器(尽管与示例中的迭代器相反)。根据您的需要,也可以使用备用的写时复制容器。
答案 5 :(得分:0)
不可能说,因为这两个代码片段不相同。
差异(对add的调用缺乏同步)可能很重要,可能不是。从你给我们的东西中不可能说出来。