synchronized是java中的一个关键字,其可确保被其修饰的代码块,在同一时间只能有一个线程可以执行。
在一般的描述中,编发编程有两个重要的概念,分别是可见性和原子性。
由于同一时间只能有一个线程执行,因此,在进入代码块的时候,会去主存中读取共享变量,在操作完成后刷回到主内存中。代码块执行过程是串行的,因此可以保证操作的原子性,同时操作完成后,会将数据回刷到主存,后续线程肯定可以拿到最新值,因此可以保证可见性。
需要注意的是,可见性和原子性是针对共享变量而言的。
在jdk1.6以后的版本中,对synchronized关键字进行了优化,引入了偏向锁和轻量级锁,锁的升级顺序为 无锁-->偏向锁-->轻量级锁-->重量级锁。锁只能升级,不能降级
- 当没有线程执行的时候,使用无锁
- 当有同一时间,只有一个线程访问的时候,是偏向锁
- 当同一时间有超过一个线程访问的时候,偏向锁会升级为轻量级锁,轻量级锁通过自旋的方式进行锁的获取
- 当轻量级锁的自旋超过了阈值,会升级为重量级锁,阈值可通过参数配置,在默认情况下,会根据程序运行情况动态调整这个阈值
TIP:当前文章仅代表个人技术总结,如有不同见解,欢迎指正