多线程 *** 作临界资源,存在线程安全问题,解决方法都是===>序列化访问临界资源
synchronized历史:
jdk1.6之前,性能低,依赖java对象加锁,创建一个对象,jvm维护一个monitor缓存;保证互斥,缓存依赖底层 *** 作系统OS中mutex互斥量(重量级锁),linux中是Pthread。jdk1.6开始,做了锁升级优化,无锁->偏向锁->轻量级锁->重量级锁(随着竞争激烈程度升级):
没有代码执行时,无锁
当来了一个线程访问时,升级为偏向锁
当来了多个线程,但是竞争不是很激烈(执行很多,交替执行),升级为轻量级锁,未拿到锁的线程不会阻塞,而是在自旋,不会让出cpu使用权
重量级锁 阻塞的线程被挂起,等待重新调度,导致用户态和内核态来回切换,对性能有较大影响
用户态与内核态:
*** 作系统中的程序,一般都是在用户态下运行的。当程序需要借助 *** 作系统来完成一些自己无法完成的 *** 作时,便会从用户态切换到内核态,如果频繁切换,这样的开销还是很大的。
重量级锁:
其实现原理是通过 *** 作系统调用MutexLock来保证竞态资源的互斥,所以会产生用户态与内核态的切换。
synchronized的使用:根据锁的力度不同区分:
1.加在静态方法上,其实是类锁,因为是静态方法,它把整个类都锁起来了
2.加在非静态方法上,锁的是调用该方法的对象,即this
3.加在代码块中
synchronized是内置锁,隐藏锁,互斥锁。
synchronized加锁是加在对象上的,下面介绍一下对象的锁状态记录:
对象锁信息
对象头:三部分mark word, metadata, 数组元信息(数据对象才有)
openjdk提供jol-core可以打印对象头信息
JVM关闭偏向锁命令: -XX:-UseBiasedLocking //关闭偏向锁(默认打开)
synchronized优化:
锁的膨胀升级(不可逆)
锁的粗化
锁的消除
自旋锁
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)