我是菜鸟:java中同步组件的深入研究

在java中,用于线程同步的有synchronized关键字,Lock等,下面对这些的内部机制原理进行分析总结下。这一节和上一节的同步器紧密关联(AbstractQuenuedSynchronizer)。同步器是构成这些同步组件的基础。

重入锁

其实在一开始看Java这一块的时候,看的很是迷糊,这个重入锁是什么意思?是重(zhong)入锁还是重(chong)入锁,傻傻分不清。当理解了其含义:其表示该锁支持一个线程对资源的重复加锁,这下就恍然大悟了。
下面先列出该锁的几个关键词:
1. 可重入
2. 可公平

可重入

什么叫做可重入?顾名思义,不解释。对于大多数锁而言,我们知道一个线程如果获取到了锁以后,其他的线程必须等待。(同步器实现的原理)那么可重入锁可实现当前线程的重新获取锁,应该如何设计?对此需要解决下面2个问题:
1. 线程再次获取锁
2. 锁的最终释放

线程再次获取锁

很明显了,在获取锁的时候,判断下是否为当前占有锁的线程,如果是就可以重新获得锁。

 锁的最终释放

每个锁都有一个计数器,当计数器的值为0的时候,表示锁被当前成功释放。
下面是针对上面的代码片段:

final boolean nonfairTryAcquire(int acquire){
   final Thread current = Thread.currentTread();
   int c = getState();
   if(c==0){// 还没有线程获取到锁
      // 通过CAS方式获取锁
   }else{ 
    if(current==getExclusiveOwnerThread()) {// 当前线程再次获取锁
       .........
    }
   }   
}

总结下处理逻辑:
通过判断当前线程是否为获取锁的线程来决定获取锁操作是否成功,若是获取锁的线程再次请求,则将同步状态值进行增加并返回true,表示获取同步状态成功。

公平

锁的公平性:FIFO
在实现的时候,唯一与非公平的锁的区别在于第一次获取锁的时候,增加了一个判断逻辑:判断加入同步队列中的当前节点是否有前驱节点,如果有前驱节点,那么表示有线程比当前线程更加早的请求锁,因此需要等到前驱节点获取并释放锁之后才能继续获取锁。
效率对比:
对于非公平锁,由于刚刚释放锁的线程,再次获取锁的机会比较大,这样可以减少上下文切换,因此其效率比较高。但是由于不是公平的,其他线程容易出现饥饿的情况。

读写锁

读写锁的使用示例:

......
ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
Lock r = rwl.readLock();
Lock w = rwl.writeLock();
......

读写锁的实现分析(经典)

读写锁的实现也是依赖于同步器来实现的,而从前面我们知道,一个同步状态表示的是锁被一个线程重复获取的次数,而读写锁需要在一个int变量上维护多线读线程和一个写线程,那么应该来如何设计呢?
一个int变量表示2个状态,那么采用 按位切割使用这个变量即可。(经典部分)。
在实际中,高16位表示读状态,低16位表示写状态。
一些值得学习的技巧:
假设当前的状态为S,获得低16位
S&0x0000FFFF
获得高16位:
S>>>16;
写状态+1:
S+1;
读状态+1:
S+(1<<16);

写锁的实现逻辑

写锁是一个支持重进入的排他锁。如果当前线程已经获取了写锁,则只需要增加写状态。如果当前线程在获取写锁的时候,读锁已经被获取或者该线程不是已经获取写锁的线程,则当前线程进入等待状态。

读锁的实现逻辑

读锁是一个支持重进入的共享锁,它能够被多个线程同时获取,在没有其他写线程访问时,读锁总会被成功的获取,而所做的只是线程安全的增加读状态。

读写锁支持  锁降级

在读写锁里有个锁降级,指的是写锁降级成为读锁,也就是指把持住当前拥有的写锁,再获取到读锁,随后释放写锁的过程。

writeLock.lock();
......
    readLock.lock();
......
writeLock.unlock();
......
   readLock.unlock();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值