显示锁ReentrantLock和Condition的使用

一、ReentrantLock
(1)、java.util.concurrent.locks包中的ReentrantLock就是重入锁,它实现了Lock接口,Lock加锁和解锁都是显示的。ReentrantLock重入锁可以实现synchronized关键字的功能。
主要方法:
lock:获得锁。
unlock:释放锁。
(2)、java对synchronized优化之后,ReentrantLock和synchronize大的区别:
a、锁的粒度,ReentrantLock更细,更灵活。
b、ReentrantLock可以指定锁的公平性。synchronize只能是非公平的。
c、ReentrantLock可以利用Condition(条件)类选择性分组唤醒线程。
d、ReentrantLock可以中断一个正在等待获取锁的线程。lockInterruptibly()。
(3)、典型的使用格式:

class X {
   private final ReentrantLock lock = new ReentrantLock();
   // ...
   public void m() {
     lock.lock();  // block until condition holds
     try {
       // ... method body
     } finally {
       lock.unlock()
     }
   }
 }

测试i++的代码:
注意:必须在finally块中调用unlock语句释放锁,以确保即使在方法体中抛出异常(try块)锁也会释放锁。否则这个锁永远不释放。

/**
 * @author monkjavaer
 * @date 2018/12/16 22:24
 */
public class ReentrantLockService{

    private Lock lock = new ReentrantLock();
    private int count = 0;

    public void getCount(){
        try {
            //获得锁
            lock.lock();
            System.out.println("thread :"+Thread.currentThread().getName()+" count = "+count++);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //在finally块中调用unlock语句,以确保即使在方法体中抛出异常(try块)也会释放锁。
            lock.unlock();
        }
    }


    public static void main(String[] args) {
        ReentrantLockService service = new ReentrantLockService();
        for(int i=0; i<100; i++){
            new Thread("" + i){
                @Override
                public void run(){
                    service.getCount();
                }
            }.start();
        }
    }

}

二、Condition
(1)、Condition通过Lock对象调用newCondition()方法获得。借助Lock,Condition可以实现wait && notify同样的功能。主要方法:
await(): 使当前线程等待
signal():唤醒一个等待的线程
signalAll():唤醒所有等待的线程
(2)、在使用Condition的方法时需要先获得锁,即调用Lock对象的lock()方法,否则会抛出IllegalMonitorStateException,因为没有监视器对象。

Condition使用实例:

/**
 * @author monkjavaer
 * @date 2018/12/18 21:14
 */
public class ConditionService {
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    public void awaitTest(){
        try {
            lock.lock();
            System.out.println("before await()");
            condition.await();
            System.out.println("after await()");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public void signalTest(){
        try {
            lock.lock();
            System.out.println("before signal()");
            condition.signal();
            System.out.println("after signal()");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        ConditionService service = new ConditionService();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                service.awaitTest();
            }
        });
        thread1.start();

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                service.signalTest();
            }
        });
        thread2.start();
    }
}

  

  

posted @ 2018-12-18 22:46  monkjavaer  阅读(641)  评论(0编辑  收藏  举报