过度使用同步会导致性能低下、死锁或其他不确定问题
- 在一个同步方法或代码块中,不要放弃对客户端的控制
- 即:在一个同步区域内部,不要调用被覆盖方法,或者是传入对象提供的方法
- 这些外来方法不可控,会带来各种问题
- 为了避免死锁和数据破坏,千万不要从同步区域内部调用外来方法
代码详见:
- 使用可重入锁:当一个线程在操作被该锁保护的数据,另一个持有该锁的不相关操作会带来灾难性后果
- 将外来方法移除同步代码块(比如代码实例中的notifyElementAdded2),可以解决test1、2出现的异常和死锁
使用并发包(concurrent Collection)
- CopyOnWriteArrayList 是ArrayList 的一个变体
同步区域内要尽可能少的做操作
同步的性能问题::
- 永远不要过度使用同步
- 在多核的时代,会失去并行的机会,会因为要保持内存的一致而导致延迟
- 过度同步会限制jvm 优化代码的执行
可变类如果需要并发执行:
- 应该把类设计成线程安全的(内部同步往往比外部锁定性能更高)
- StringBuffer 内部同步
- StringBuilder是线程不安全的,而StringBuffer是线程安全的
内部同步了类,可以考虑使用别的方法实现高并发:
- 比如:分拆锁、分离锁、非阻塞并发控制
如果方法修改了静态域,必须同步这个域的访问
- 因为外部同步是不可能的