java学习笔记之多线程的锁接口Lock

       众所周知,多线程的弊端是会使代码受到并发访问的干扰,解决的办法就是同步机制。同步的两种常见形式分别是同步代码块和同步函数,两种形式的锁都是隐式锁,前者持有的锁可以是任意对象,后者持有的锁是默认的this。

      从JDK1.5开始,根据面向对象的思想,将锁封装了起来,对外提供Lock接口,并提供了对锁的显式操作。Lock接口的出现比synchronized有更多的操作,是同步的替代。

      将锁单独封装的好处就是可以更灵活的使用锁,Lock接口的实现允许锁在不同的作用范围内获取和释放,并允许以任何顺序获取和释放多个锁,从而支持使用这种技术。

      查阅API,在java.util.concurrent.locks包里可以查到Lock接口。主要的方法有

      lock()--->获取锁。

      unlock()--->释放锁

      需要注意的是,synchronized实现同步的时候,当同步代码结束,锁自动释放,但是使用lock接口实现同步就会失去锁的自动释放功能。如果同步的代码块抛出异常,锁不能被释放,会导致其他线程无法执行。因此必须将解锁操作写到finally子句中。

如何使用Lock接口实现同步呢?

      Lock接口的已知实现类包括ReentrantLock,ReentrantReadWriteLock,ReentrantReadWriteLock.WriteLock.

Lock lock  = new ReentrantLock();

lock.lock();

try{

             ......;

        }

        finally{   

        lock.unlock();

        }

        如果用Lock接口实现同步,原同步代码块或同步函数中的wait();notify();notifyAll()方法就不能用了。根据面向对象的方法,将原来的同步监视器方法封装到了condition对象中。而Lock接口的灵活之处体现在一个Lock接口可以支持多个condition对象,相对应的方法是await();signal();signalAll().

用法可以查看API的示例

 

 class BoundedBuffer {
   final Lock lock = new ReentrantLock();  //锁对象
   final Condition notFull  = lock.newCondition();  //条件对象
   final Condition notEmpty = lock.newCondition(); 

   final Object[] items = new Object[100];
   int putptr, takeptr, count;

   public void put(Object x) throws InterruptedException {
     lock.lock(); //获取锁
     try {
       while (count == items.length) 
         notFull.await();
       items[putptr] = x; 
       if (++putptr == items.length) putptr = 0;
       ++count;
       notEmpty.signal();
     } finally {
       lock.unlock(); //释放锁
     }
   }

   public Object take() throws InterruptedException {
     lock.lock();
     try {
       while (count == 0) 
         notEmpty.await();
       Object x = items[takeptr]; 
       if (++takeptr == items.length) takeptr = 0;
       --count;
       notFull.signal();
       return x;
     } finally {
       lock.unlock();
     }
   } 
 }

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值