Lock和Condition(可重入锁)

本文详细探讨了Java中Lock接口的特性,包括响应中断、支持超时和非阻塞获取锁,对比synchronized关键字,解释了ReentrantLock的可重入性和公平策略,以及最佳实践。

Lock有别于synchronized隐式锁的三个特征:能够响应中断。支持超时和非阻塞地获取锁,也就是说lock比synchronized的功能丰富。

JavaSDK并发包通过Lock和Condition两个接 口来实现管程,其中Lock用于解决互斥问题,Condition用于解决同步问题 。

Lock接口的三个方法:

//	⽀持中断的API 
void	lockInterruptibly() throws	InterruptedException; 
//	⽀持超时的API
boolean	tryLock(long time, TimeUnit	unit) throws	InterruptedException; 
//	⽀持⾮阻塞获取锁的API 
boolean	tryLock();
如何保证可见性
class X	{	
    private final Lock	rtl	= 	new	ReentrantLock();		
    int	value;		
    public	void	addOne()	{				
        //	获取锁				
        rtl.lock();						
        try	{						
            value =1;				
        } finally {						
            //	保证锁能释放						
            rtl.unlock();				
        }		
    } 
}
什么是可重入锁(ReentrantLock)

指线程可以重复获取同一把锁 。

//⽆参构造函数:默认⾮公平锁 
public	ReentrantLock()	{				
    sync	=	new	NonfairSync(); 
} 
//根据公平策略参数创建锁 fair=true是公平锁
public	ReentrantLock(boolean fair){				
    sync = fair ? new FairSync() : new NonfairSync(); 
}

非公平可重入锁示例:

线程可以重复获取同一把锁。

   /**
     * 当线程t执行到①处时,已经获取到了锁rtl,
     * 当在①处调用get()方法时,会在②再次对锁rtl执行加锁操作。
     * 此时,如果锁	rtl	是可重入的,那么线程T1可以再次加锁成功;如果锁	rtl	是不可重入`	   * 的,那么线程t此时会被阻塞。
     */
public class ReentrantLockExample {
    private final Lock rtl = new ReentrantLock();
    int value;

    public int get() {
        //	获取锁
        rtl.lock(); //②
        try {
            return value;
        } finally {
            //	保证锁能释放
            rtl.unlock();
        }
    }

    public void addOne() {
        //	获取锁
        rtl.lock();
        try {
            value = 1   get();    //①
        } finally {
            //	保证锁能释放
            rtl.unlock();
        }
    }

可重入函数: 多个线程可以同时调用该函数。

可重入函数是线程安全的。

非公平锁与公平锁

ReentrantLock这个类有两个构造函数,一个是无参构造函数,一个是传入fair参数的构造函数。fair参数代表的是锁的公平策略,如果传入true就表示需要构造一个公平锁,反 之则表示要构造一个非公平锁。

 //创建ReentrantLock时传入true是公平锁
private final Lock rtl = new ReentrantLock(true);
 //false或者不传值是非公平锁
private final Lock rtl = new ReentrantLock();
用锁的最佳实践
  1. 永远只再更新对象的成员变量时加锁。
  2. 永远只在访问可变的成员变量时加锁。
  3. 永远不再调用其它对象的方法时加锁。
  4. 减少所得持有时间,减小锁的粒度。
同步与异步
  • 调用方法如果需要等待结果,就是同步;如果不需要等待结果就是异步。
  • 同步是Java代码默认的处理方式。

如何实现程序支持异步:

  1. 异步调用: 调用方创建一个子线程,再子线程中执行方法调用。
  2. 异步方法: 被调用方;方法实现的时候,创建一个显得线程执行主要逻辑,主线程直接return。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘彦青-Yannis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值