在Collection框架中,为什么外部同步比内部同步更快(Vector,HashTable等)?即使他们都使用相同的机制?为什么外部同步比内部更快?
内部和外部同步的确切含义以及它们如何相互区别?
如果有人可以用例子来解释,这真的很有帮助。
在Collection框架中,为什么外部同步比内部同步更快(Vector,HashTable等)?即使他们都使用相同的机制?为什么外部同步比内部更快?
内部和外部同步的确切含义以及它们如何相互区别?
如果有人可以用例子来解释,这真的很有帮助。
内部和外部同步究竟有什么意义,它们又有什么不同?
外部同步是当呼叫者(你)使用关键字或其它锁,以防止另一个类被多个线程访问。如果有问题的课程通常使用而不是本身同步 - SimpleDateFormat
是一个最好的例子。如果您需要线程之间的信号传输,即使在处理并发收集时也可以使用它。
为什么外部同步比内部同步更快(Vector,HashTable等)?即使他们都使用相同的机制?
外部同步是而不是必然更快。通常,一个类可以精确地确定何时需要围绕代码的关键部分进行同步,而不是调用方包含块中的所有方法调用。
如果你在谈论一般建议不使用Vector
和HashTable
,转而使用Collections.synchronizedList(...)
或synchronizedMap(...)
方法,那么这是因为Vector
和HashTable
被看作是旧的/旧的过时的类。被包装的ArrayList
或HashMap
被视为更好的解决方案。
有时候,正如@Chris指出的那样,当您需要对一个接一个的类进行一些更改时,外部同步可以更快。通过外部锁定一次,然后对类进行多重更改,这比内部锁定的每个更改都更好。一次锁定比多次锁定呼叫更快。
如果有人可以用例子来解释,这真的很有帮助。
而不是Vector
,人们通常建议包装ArrayList
作为更好的性能。这将非同步的ArrayList
类封装在一个包装类中,该类将其与外部同步。
List<Foo> list = Collections.synchronizedList(new ArrayList<Foo>());
在与一般的外部内部条件,认为要允许多个线程同时使用了下列类:
public class Foo {
private int count;
public void addToCount() {
count++;
log.info("count increased to " + count);
}
}
你可以使用外同步和每一个电话换到addToCount()
在块:
synchronized (foo) {
foo.addToCount();
}
或者类本身可以使用内部同步哟做锁定ü。
public void addToCount() {
int val;
synchronized (this) {
val = ++count;
}
// this log call should not be synchronized since it does IO
log.info("count increased to " + val);
}
当然,Foo
类确实应该在这种情况下使用AtomicInteger
和照顾自己的重入内:
private final AtomicInteger count = new AtomicInteger(0);
public void addToCount() {
int val = count.incrementAndGet()
log.info("count increased to " + val);
}
感谢您使用良好的示例进行探索...... – Rajeev
假设你在银行工作。每次需要使用保险箱时,都需要解锁,然后在完成使用后重新锁定。
现在我们假设您需要携带50个箱子进入保险箱。你有两个选择:
哪一个更快? (第一个选项是内部同步,第二个选项是外部同步。)
好的类比,但如果您需要退出银行每一次。你不能锁定城市或国家 – Mordan
@Mordan我认为你把这个比喻拉得太远了。电脑上的抽象化并不完全受到市政府的阻碍。 Java JVM就是一个很好的例子 - 当它们进行垃圾收集时,它们的一些实现会执行“停止世界”锁定,从而防止所有事情从运行到完成。我并不是说你应该为此而努力,但这并非闻所未闻。 –
轻微抛开:通常比使用同步集合编写线程安全代码要好得多。 (例如,无锁并发数据结构,在无需阻止时会产生最小开销。) – millimoose