锁的选择和读写锁

前言

当你再使用并发的时候,你可能会陷入疑问,内部锁和显式锁怎么选择?你可能有一种被水淹没,不知所措的感觉,如果你问我这个问题,针对于我目前手上的项目,我会毫不犹豫的回答你,内部锁!

探究内部锁和显式锁

为何我会选择内部锁,很多人可能会问,显式锁的性能不是高于内部锁吗,那我只能说,你的眼光可能还是局限于JAVA5时代,可能你说的对,JAVA5的时候,显式锁和内部锁他们相差甚远,你可以认为显示锁吊打内部锁,因为内部锁需要切换上下文。但是到了JAVA6,内部锁已经被优化,他的性能大大提升和显式锁差不多了,显示锁绝对是最危险的东西,因为你可能忘记了unlock,如果发生了死锁,你只会问:发生肾么事了?然后陷入无助的寻找,当然了在6的时候,你可以从线程信息中获取到加锁信息。但是显式锁的非块特性,让你不能依赖栈的结构,倒不如使用内部锁,内部锁发生死锁,你是肯定知道的。内部锁是内置于JVM中的,未来一定是更倾向于内部锁,内部锁可以减少不必要的竞争(jvm优化)当然了你对程序的伸缩性有要求,你想做一些特殊操作,例如中断,你可以使用显式锁否则绝对不是明智之选,不要单纯为了使用而使用它。这是愚蠢的事。

读写锁

ReentrantLock绝对是一个互斥锁,这个自然不用多说,不会有老六会窃取到正在使用的锁,我的意思是只能有一个线程获取这个锁,我现在有一个数据库,以读为主,利比如:系统配置还有我的年度计划。那么这样一个锁会不会过于苛刻了呢。对性能是不是不太友好,那我觉得只要我读的是最新的数据,这就够了,
而且我在读的时候,没有老六来偷袭,去改我的数据,即使老六改了,我也能看到。
那么选择ReadWriteLock吧。

public interface ReadWriteLock {
    /**
     * Returns the lock used for reading.
     *
     * @return the lock used for reading
     */
    Lock readLock();

    /**
     * Returns the lock used for writing.
     *
     * @return the lock used for writing
     */
    Lock writeLock();
}

当初设计这个锁出来肯定是为了提升性能的,而不是吃的太饱。当然了,读写锁在多处理器的情况下,以读为主的情况确实能提升性能,因为读写分开,多个访问(让我看看),性能自然提升了,这和没加锁没有区别的
在其他情况他的性能并不如独占锁,所以说我们当然可以把读写锁置换成独占锁。现在我们从多个角度来分析读写锁的。

优先释放给的是谁?

我现在写者写完了,OK了,有多个读者和写者在等,谁先来?

闯入

当锁释放,读者是否能够闯入?

重入

读写锁允许重入么?

升级降级

当我有一个写锁,它可以降级成读锁并且隔离其他写锁?一个读锁可以升级为写锁吗,那么我有两个读锁,他们可以同时升级吗?可是不要忘记,读锁是独占锁哦。

我对以上的问题做个解答:首先,读写锁是可重入锁,他默认是闯入锁,当然你也可以让他成为公平锁。公平锁,我等的时间长,锁交给我,闯入锁,我闯入的时间正好,锁交给我。如果我是一个读者,我获取了锁,现在有写的请求了。我是无法获得读写锁的,让写者先来,写者写完了,我才能获得读写锁。写者可以降级为读者,但是读者无法升级为写锁,原因上面其实已经说了,在JAVA5中,我们无法得知读者身份,在JAVA6中,我们可以得到他们的身份了。当锁被持有时间长,并且资源其实不怎么改动,读写锁能提升并发性。

总结

如果没有骚操作,建议用内部锁,并发量越大,读的请求越多,读写锁性能越好。反之独占锁。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值