日常小结-java中同步方式概述
来源:互联网 发布:2016年餐饮业数据分析 编辑:程序博客网 时间:2024/04/28 07:03
本文概述了一线java中三种实现同步的方式的异同,volatile、synchronized和Lock相关类
volatile
volatile 可以看成是一种轻量化的同步方式。它不会引起线程的切换和调度。
从原理上说volatile实际上是禁止缓存标志位。现代计算机cpu不会直接和内存交互,尤其是有多个cpu的计算机,通常会将内存中的一部分以缓存行的形式读取到缓存中,每个cpu都有自己的缓存,cpu直接与缓存进行交互以提高cpu效率。而volatile标志位产生两个结果,1会使得包含当前对象的缓存行立刻写回系统内存中。2会使得其他cpu中当前对象的缓存行失效。
由此原理会有一些volatile的优化技术,比如填充等,详见《java并发编程技术》P10
这里需要注意的是volatile只能实现单步操作的原子性,比如说读取或者写入,但是i++这种自增操作属于复合操作不能保证原子性。
volatile可以作为线程传递消息的一种方式。
synchronized
synchronized是java的管程技术的体现。管程的定义详见《现代操作系统》P77,在任意时刻管程中只会有一个活跃的进程。synchronized包括的代码块或者方法就是临界区。管程通常结合条件变量,但java没有使用条件变量,而是使用对象本身作为管程的锁,在任意时刻只有一个线程能拥有该对象作为进入管程的锁。同事所有对象都有wait和notify方法来实现类似条件变量的sleep和wakeup()操作但可以出现中断异常,需要java自己处理,synchronized使得java的所有对象都可以作为锁实现。
在1.5之前所有的synchronized都是重量级锁。在1.5之后synchronized的实现的锁分成了3个等级,即偏向锁、轻量级锁、重量级锁三种。所有对象的锁只能升级不能降级。
偏向锁用在无竞争状态下,如果一个锁总是被同一个线程获得,则这个锁只会被标记为偏向锁。如果出现竞争则撤销标记。偏向锁的获得和是否不需要cas操作来加锁和解锁。只需要修改对象头的markword即可。
轻量级锁使用自旋实现等待而不是使用阻塞。如果自旋失败则会膨胀成为重量级锁。自旋会消耗cpu时间。但是少量的消耗时间代价抵得上上下文切换的代价。并且得到相应快的响应时间
重量级锁就是典型概念中的锁。使用阻塞等待其他线程释放锁。需要上下文切换,追求的是最大吞吐量,不消耗cpu。
除了偏向锁之外所有的锁都需要使用CAS实现。具体的实现请见《java并发编程艺术》P12-P16.
Lock
相对与synchronized,lock是更为精细的调控锁的方式。比如synchronized必须使用代码块或者方法包裹,在获取和释放多个锁时必须安装相应的顺序和可见性释放,而lock就没有这样的要求。而且lock也具有阻塞获取和一定时限获取等更为灵活的操控方式。但是通常需要编程人员自己捕获异常。
Lock的使用还可以结合条件变量condition。Lock在java中的基本实现是ReentrantLock。而ReentrantReadWriteLock是读写锁。
- 日常小结-java中同步方式概述
- Java日常小结
- Java日常小结
- Java日常小结
- java中同步方式--synchronized
- Java处理线程同步/线程安全的方式概述
- java中webservice生成/调用方式小结
- java同步:小结
- 概述叠片式过滤器日常维护中常见问题
- 日常小结-java何时抛出异常
- 日常小结-java随机数类Random
- 日常小结-java静态类及其应用
- 日常小结-java线程状态的转移
- 日常小结篇-java异常处理
- 日常小结
- 日常小结
- Java之线程同步概述
- 日常小结-协议小结
- 登录圆形头像之网络加载与缓存到本地
- 安装Python机器学习库sklearn
- 编程游戏
- 实现日期的增加
- JSP中的EL表达式
- 日常小结-java中同步方式概述
- HTML5 地理位置
- Python中用format函数格式化字符串
- C语言实验——时间间隔
- leetcode258: Add Digits
- 第八周—兑换钱
- 简单的基于dubbo的调用
- java 注解——Annotations Basics
- 消息称新MacBook暂时不会采用电子墨水键盘