Java 锁timeout实现_Java多线程并发07——锁在Java中的实现

上一篇文章中,我们已经介绍过了各种锁,让各位对锁有了一定的了解。接下来将为各位介绍锁在Java中的实现。关注我的公众号「Java面典」了解更多 Java 相关知识点。

在 Java 中主要通过使用synchronized 、 volatile关键字,及 Lock 接口的子类 ReentrantLock 和 ReadWriteLock 等来实现加锁。

synchronized

属性

synchronized 属于独占式的悲观锁,同时属于可重入锁。

作用

synchronized 可以把任意一个非 NULL 的对象当作锁。其在不同场景下的作用范围如下:

作用于方法时,锁住的是对象的实例(this);

作用于静态方法时,锁住的是Class实例,会锁住所有调用该方法的线程。(又因为Class的相关数据存储在永久代 PermGen【Jdk1.8 则是 metaspace】,永久代是全局共享的,因此静态方法锁相当于类的一个全局锁);

作用于一个对象实例时,锁住的是所有以该对象为锁的代码块。

实现

它有多个队列,当多个线程一起访问某个对象监视器的时候,对象监视器会将这些线程存储在不同的容器中。

58bb131dfb8f397ab0c3977a52a76287.png

Wait Set:存储调用 wait 方法被阻塞的线程;

Contention List(竞争队列):所有请求锁的线程首先被放在这个竞争队列中;

Entry List:Contention List 中那些有资格成为候选资源的线程被移动到 Entry List 中;

OnDeck:任意时刻,最多只有一个线程正在竞争锁资源,该线程成为 OnDeck;

Owner:当前已经获取到所资源的线程被称为 Owner;

!Owner:当前释放锁的线程。

volatile

属性

比 sychronized 更轻量级的同步锁

适用场景

使用 volatile 必须同时满足下面两个条件才能保证在并发环境的线程安全:

对变量的写操作不依赖于当前值(比如 i++),或者说是单纯的变量赋值(boolean flag = true);

不同的 volatile 变量之间,不能互相依赖,只有在状态真正独立于程序内其他内容时才能使用 volatile。

对 volatile 变量的单次读/写操作可以保证原子性的,如 long 和 double 类型变量,但是并不能保证 i++ 这种操作的原子性,因为本质上 i++ 是读、写两次操作。

Lock

Java 中的锁都实现于 Lock 接口,主要方法有:

void lock(): 用于获取锁。如果锁可用,则获取锁。 若锁不可用, 将禁用当前线程,直到取到锁;

boolean tryLock():尝试获取锁。如果锁可用,则获取锁,并返回 true, 否则返回 false;

该方法和lock()的区别在于,如果锁不可用,tryLock()不会导致当前线程被禁用。

t

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值