java中锁机制
java堆中存放的是所有对象,方法区中存放着类信息、常量、静态变量等。当多个线程在竞争其中的一些数据时,需要锁机制对其进行限制。
每个对象都拥有一把锁,锁存放在对象中,锁中记录了当前对象被哪个线程占用。
java中synchronized关键词可以用来同步线程,被编译后会生成monitorenter和monitorexit两个字节码指令来进行线程同步。
关于monitor
当一个线程进入了monitor,其他线程只能等待,只有当该线程退出,其他线程才有进入的机会。
synchronized的同步机制:
当A进入monitor,它就处于active状态。
如果该线程需要暂时让出执行权,该线程就进入wati set,状态被标记为waiting。
当线程B进入monitor后并完成了任务,可以通过notify的形式来唤醒wait set中的线程A,让线程A再次进入monitor来进行任务。
*Java6中引入四种锁:
*
无锁:没有对资源进行锁定,所有线程都能够访问到同一资源。
1.无竞争
2.存在竞争,非锁方式同步线程。(CAS,无锁性,只让一个线程 进来,效率高)
偏向锁:只让被提前设定的线程进入。(偏爱)通过线程id来确认当前想要获得对象锁的这个线程是不是老顾客。如果发现有多个线程来竞争时,偏向锁升级为轻量级锁。
轻量级锁:
当其他线程也想要进入该资源中时,就会发生自旋(即不断循环尝试着看一下目标对象的锁有没有被释放,如果释放了就获取,如果没有就一直循环)自选相当于cpu空转(采用适应性自旋优化)。
重量级锁:自旋等待的线程超过一个,轻量级锁就会升级为重量级锁。需要通过Monitor来对线程进行控制,将会完全锁定资源。
对应了mark word中的四种状态
总结: