JAVA锁机制

来源:互联网 发布:数据分析的方法和模型 编辑:程序博客网 时间:2024/05/21 21:36
synchronized和Lock均为可重入锁。即可为该对象多次加锁,通过锁标志+1进行操作;当所标志为0时,释放所。重入锁目的是为防止死锁发生。

synchronized:基于系统内核实现线程等待(通过linux系统pthread_mutex_lock命令进行等待)。
        a、将线程通过CAS操作放入ContentionList队列头部。
        b、当Owner拥有锁者unlock时,会将ContentionList队列中的内容移动到EntryList中,并将头结点设置为ready,可以去竞争锁。
        c、当Owner拥有锁者被wait时,进入waitSet队列。被notify时重新进入EntryList中,进行锁竞争。

        自旋锁:线程被阻塞为系统阻塞,处于内核态,java执行为用户态;为避免经常在用户态和内核态频繁切换导致性能下降,实现了自旋锁(即没竞争到锁后,自己循环一段时间竞争锁,如果超期没获得,再阻塞)。

        偏向锁:线程加锁操作采用CAS操作。当线程已经获得锁后,再重入该锁时,后续操作将不会采用CAS,因为不存在锁竞争。

        

Lock:JAVA自己实现。基于AQS非阻塞队列和CAS原子操作实现。
        a、将所有请求锁的线程通过CAS放入AQS队列(FIFO)中,如果失败则无线循环放入。阻塞调用LockSupport.park完成,park调用sun.misc.Unsafe.park本地方法实现。最终也是调用pthread_mutex_lock。AQS也是一个CHL队列,即实现了自旋锁,所以这是一个非公平锁。
        b、也实现了自旋锁和偏向锁(JAVA代码实现)。

俩种锁对比:Lock扩展性强,因为是JAVA实现的,可以基于AQS实现其他锁功能(读写锁、中断锁)。



0 0