《多线程编程》学习之九:Lock的使用

一、ReentrantLock类的使用

1.1)使用ReenrtantLock类实现同步

          在java多线程中,可以使用synchronized关键字实现线程之间的互斥,而JDK1.5新增的ReentrantLock类也能达到类似的效果,且使用上比synchronized更灵活、强大。下面例子中,调用ReentrantLock类的lock()获取锁,调用unlock()释放锁。



          一个线程打印完毕后将锁释放,其它线程才可获取锁进行打印。但线程之间打印的顺序是随机的。


1.2)使用Condition类实现等待/通知机制:

        synchronized关键字与wait()和notify()/notifyAll()结合可以实现等待/通知机制,ReentrantLock类与Condition类结合使用也可以实现同样的功能,并且可以有选择型地进行线程通知(在一个Lock对象里创建多个Condition对象)。




          可见成功地实现了等待/通知模式。由之前的学习知道,Object类的wait()和notify()/notifyAll()方法必须用在同步方法/代码块中,这里Conditon类的await()与signal()方法在调用之前必须先调用ReentrantLock类的lock()方法获得同步监视器。



1.3)使用多个Condition对象实现通知部分线程:

          在一个Lock对象里可以创建多个Condition(对象监视器)实例,线程对象可以注册在指定的Condition中,从而可以有选择性地唤醒某些线程。






          从运行结果可见,实现了只唤醒threads_A线程组,而threads_B线程组没有被唤醒。


1.4)实现生产者/消费者模式:一对一






1.5)实现生产者/消费者模式:多对多







              实现了多个生产者与消费者线程之间的交替运行,注意到唤醒的线程有可能是同类线程。


1.6)公平锁与非公平锁

          所谓“公平锁”,是指线程获取锁的顺序是按照线程加锁的顺序来分配,而非公平锁则随机获取锁,是一种抢占机制。可以通过new ReentrantLocak(true)来创建公平锁,但并不是绝对的公平。


1.7)使用Condition实现顺序执行






          可见三个线程组之间是交替进行的,但组内的顺序不确定。


二、ReentrantReadWriteLock类的使用

        上面介绍的ReentrantLock类具有完全排他的效果,这样虽然保证了实例变量的线程安全,但效率却很低。使用ReentrantReadWriteLock类可以提高运行效率。读写锁中,读锁是共享锁,写锁是排他锁;多个读锁之间不互斥,而读锁与写锁、写锁与写锁之间是互斥的。

1)读锁与读锁之间不互斥





          可见两个读线程几乎同时进入lock()方法后的代码,表明使用lock.readLock()读锁可以提高程序运行的效率,允许多个线程同时执行lock()方法后的代码。


2)写锁与写锁互斥

          在上面例子的基础上,测试代码改为:



          可见使用写锁lokc.writeLock()的效果是,同一时间内只允许一个线程执行lokc()方法后面的代码。


3)读写、写读互斥

        读写互斥的测试代码及运行结果如下:



         可见先读后写时,读写之间是互斥的。写读互斥的测试,则使写线程先运行,读线程后运行,结果是一样的。

也就是说,只有“读读”不互斥,“写写”、“写读”、“读写”都是互斥的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值