多线程操作共享数据,加锁保证访问共享数据的线程安全性
1、静态方法,类对象
2、非静态方法,当前对象-this
3、代码块,指定对象-lock
1、代码执行完毕
2、异常结束
预防饥饿
代码块加锁,通过monitorenter、monitorexit指令实现
静态方法、方法加锁,通过在方法的flags中加入ACC_SYNCHRONIZED实现
1、原子性,互斥锁monitorenter、monitorexit、ACC_SYNCHRONIZED
2、有序性,通过Acquire屏障、Release屏障保证代码块内部重排
3、可见性,进入synchronized代码块时,从主内存获取变量,退出时刷新到主内存
正常退出、异常退出
获取锁时,检查锁状态,为0表示没有被占用,每一次进入方法,status加1
释放锁时,每一次退出方法,status减1
避免死锁
as-if-serial语义,指编译器、处理器无论如何优化,单线程执行结果不变
尝试获取锁的线程不会立即阻塞,循环获取锁
1、减少锁竞争
2、减少锁粒度
3、减少锁时间
1、锁对象不能为null
2、作用域不能过大,影响性能
3、避免死锁
1、不能设置锁超时时间
2、不能通过代码释放锁
3、容易死锁
1、资源竞争激烈,lock性能更好
2、手动释放锁
3、只能写在代码里
1、synchronized依赖JVM,ReentrantLock依赖API
2、ReentrantLock功能:等待可中断、公平锁、锁绑定条件
Copyright ©2010-2022 比特日记 All Rights Reserved.