【发布时间】:2014-01-07 14:51:45
【问题描述】:
阅读this one 后出现问题。同步对象和非同步对象有什么区别?为什么非同步对象比同步对象执行得更好?
【问题讨论】:
-
一次只有一个线程可以使用同步对象,因此其他线程必须等待..
-
加上锁定机制会产生成本,因此即使使用单线程,同步也会变慢。
标签: java multithreading synchronized
阅读this one 后出现问题。同步对象和非同步对象有什么区别?为什么非同步对象比同步对象执行得更好?
【问题讨论】:
标签: java multithreading synchronized
同步对象和非同步对象有什么区别?为什么非同步对象比同步对象表现更好?
HashTable 被认为是同步的,因为它的方法被标记为synchronized。每当线程进入synchronized 方法或synchronized 块时,它必须首先获得对与正在同步的对象实例关联的监视器的独占控制权。如果另一个线程已经在同一对象的synchronized 块中,那么这将导致线程阻塞,正如其他人所提到的那样,这是一种性能损失。
但是,synchronized 块也会在之前和之后进行内存同步,这会影响内存缓存,并且还会限制代码重新排序/优化,这两者都会对性能产生重大影响。因此,即使您有一个线程调用进入synchronized 块(即没有阻塞),它也会比没有运行慢。
线程程序的真正性能改进之一是通过单独的 CPU 高速内存缓存实现的。当线程程序进行内存同步时,需要将已更新的缓存内存块写入主内存,并且对主内存进行的任何更新都会使本地缓存内存无效。通过同步更多,即使在单线程程序中,您也会看到性能下降。
顺便说一句,HashTable 是一个老班。如果你想要一个可重入的Map,那么应该使用ConcurrentHashMap。
【讨论】:
通俗的讲Synchronized Object是单线程模型,如果有2个线程想修改Synchronized Object。如果第一个获得了Object的锁,那么最后一个应该是waite。但是如果Object是Unsynchronized,他们可以同时操作Object,这就是Unsynchronized不安全的原因。
【讨论】:
synchronized 块中还有其他性能影响。我已经在我的回答中解决了这些问题。
为了使同步工作,JVM 必须防止多个线程一次进入同步块。与不存在同步块的情况相比,这需要额外的处理,这会给 JVM 带来额外的负载,从而降低性能。
当同步发生时,确切的锁定机制在How the Java virtual machine performs thread synchronization中有解释
【讨论】:
同步:
数组列表是非同步的,这意味着多个线程可以工作 同时在 Array List 上。例如如果一个线程正在执行 对数组列表的添加操作,可以有另一个线程 在多个数组中同时对 Array List 执行删除操作 线程环境
Vector 同步时。这意味着如果一个线程正在处理 向量,没有其他线程可以掌握它。与数组列表不同,只有 一个线程一次可以对向量执行一个操作。
性能:
与同步操作相比,同步操作消耗更多时间 非同步的,所以如果不需要线程安全 操作,Array List 是更好的选择,因为性能会 由于并发进程而得到改进。
【讨论】:
同步很有用,因为它允许您防止代码同时运行两次(通常称为并发)。由于多种原因,这在线程环境中很重要。为了提供这种保证,JVM 必须做额外的工作,这意味着性能会下降。因为同步要求一次只允许执行一个进程,所以它会导致多线程程序的运行速度与单线程程序一样慢(或更慢!)。
请务必注意,性能下降的幅度并不总是很明显。视情况而定,下降幅度可能很小或很大。这取决于各种各样的事情。
最后,我想添加一个简短的警告:使用同步的并发编程是hard。我发现通常其他并发控制更适合我的需要。我的最爱之一是Atomic Reference。这个实用程序很棒,因为它非常严格地限制了同步代码的数量。这使得它更易于阅读、维护和编写。
【讨论】: