Java中的可重入锁

使用Java进行多线程开发,锁的使用是非常重要的,也是一个几乎不可避免的问题。那么,就让我们来聊一聊java中的锁是什么东西。

首先,既然要使用锁,那么java中到底什么是锁?为什么要使用锁?

现在有两个线程,需要同时访问一个共同的资源Person。一个是读取Person的线程,一个写入Person的线程。Person对象有两个属性,一个是性别,一个是名字。

当Person对象被创建出来,性别、姓名都是空的。这时就有写线程来开始写入数据。

虽然写线程先于读线程工作,但是, 由于写性别和读性别两个操作不是原子的。这就导致读线程只读取了半个数据,在读线程看来,Person对象的性别是不存在。

这就引出了java中的线程不安全的问题,避免类似的问题发生,我们就需要使用锁。让写线程在修改对象前,先加锁,然后完成对共享资源的填充赋值,再释放锁。而读线程也是一样,先取得锁,再读,然后释放锁。这样就可以避免发生这种情况。

重入锁是什么

现在大家知道为什么要使用锁了。那么java中什么是可重入锁呢。一般情况下,锁可以控制多线程的行为。可以让线程变的安全,但是如果一个线程连续对同一个锁进行lock会怎样,如果是一般的锁可能就直接卡死了,这样非常不友好。

所以在我们平时开发的过程中还要注意锁的死循环问题,就是死锁的发生,一不小心可能就会发生死锁,这就引出了java中的可重入锁了。

重入锁使得同一个线程可以对同一把锁,在不释放的前提下,反复加锁,而不会导致线程卡死。因此,如果我们使用的是重入锁,那么上述代码就 可以正常工作。你唯一需要保证的,就是unlock()的次数和lock()一样多。这样是不是方便很多呢?

Java中的可重入锁 

Java中的锁都来自与Lock接口,重入锁提供的最重要的方法就是lock()

· void lock():加锁的方法,此时的锁已经被别人占用就会一直等待下去。

这个lock()方法,是锁的最基本的方法,用这个方法拿到锁就返回,拿不到就一直处于等待状态。所以我们在使用这个方法的时候要非常的小心,在一些比较复杂的情景下还是要注意不要发生死锁的情况。

当然,肯定有防止死锁发生的方法,如下:

· boolean tryLock(long timeout, TimeUnit unit):这个方法是去尝试获取锁,他有一个超时等待的时间,超过这个时间就不在去获取了,也可以响应中断。

这个方法是比较有价值的,在jdk的底层代码中被大量的使用

lock()、tryLock()的比较:

1.tryLock 不会一直等待。他有超时时间和响应中断可以打破死锁的形成。同时释放自己已经得到的资源。这就可以避免死锁的发生,这也是线程之间的谦让机制。

2.可以在应用程序进行自旋去尝试获取锁,也可以自定义尝试获取锁几次,也可以直接选择放弃获取,释放资源。

3.如果此时,程序正好收到关机信号,等待锁的过程中可以响应中断,中断就会触发,进入中断异常后,线程就可以做一些清理工作,从而防止在终止程序时出现数据丢失、数据写坏等不好的情况发生。

在我们使用java给我们提供的锁的时候,一定要记得释放锁,不然就会出现程序崩溃,出现异常

· void unlock() :释放锁

此外, 重入锁还有一个不带任何参数的tryLock()。

· boolean tryLock()

这个不带任何参数的tryLock()不会进行任何等待,如果能够获得锁,直接返回true,如果获取失败,就返回false,特别适合在应用层自己对锁进行管理,在应用层进行自旋等待。

Condition是什么

Condition可以理解为重入锁的伴生对象。它提供了在重入锁的基础上,进行等待和通知的机制。可以使用 newCondition()方法生成一个Condition对象

Condition的使用是什么样的呢?来看下这个ArrayBlockingQueue。ArrayBlockingQueue是一个队列,你可以使用他的take方法拿元素,也可以把元素加入到队列(enqueue)中去。当然,这是有条件的,当队列是空的时候,我们去拿元素的时候就会出现等待的情况,什么时候有元素了再返回我们拿到的元素,这中情况就可以使用Condition对象了。

在ArrayBlockingQueue中就维护了一个Condition对象

这个notEmpty 就是一个Condition对象。它用来通知其他线程,ArrayBlockingQueue是不是空着的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值