锁的基本使用

锁一般都是实现Lock接口,所以了解Lock接口的API,基本就会用锁了。

Lock接口

方法 说明
void lock() 获取锁。调用方法会获取锁,直到锁获取后返回
void lockInterruptibly() throws InterruptedException 可中断获取锁,在获取锁的过程中可以被中断,被中断后抛出异常返回
boolean tryLock() 尝试非阻塞的获取锁,立即返回,拿到锁返回true,否则false
boolean tryLock(long time, TimeUnit unit) throws InterruptedException 超时的获取锁
返回的情况
1. 在超时时间内获取到了锁,返回true
2. 被中断了,抛出异常返回
3. 超时时间到,返回false
void unlock() 释放锁
Condition newCondition() 获取等待通知组件,只有拿到了锁,才能拿到这个对象,调用wait()方法,调用后释放锁

带try的这种方法,就是拿的到就拿,拿不到就算了,会立即返回;这个就想学习一样,学的会就学,学不会就算了,当然这是错误的观点了。

可以看到和synchronized相比Lock要灵活和强大,使用会稍微麻烦一点:

  1. synchronized是隐式获取释放锁,比较简单和固定,Lock是需要手动获取锁和释放,比较灵活
  2. Lock可以尝试非阻塞获取锁、能被中断的获取锁、能够带超时的获取锁, synchronized不能做到

一个例子

static class Account {
    // 搞个可重入锁练手
    private Lock lock = new ReentrantLock();
    private Integer money;

    public Account(Integer money) {
        this.money = money;
    }

    public boolean draw(int count) {
        // 加锁不要放到try里边,因为如果在获取锁(自定义锁的实现)时发生了异常,异常抛出的同时,也会导致锁无故释放
        lock.lock();
        try {
            if (money >= count) {
                System.out.println("取走" + count);
                money -= count;
                return true;
            } else {
                System.out.println("钱不够了,去关注微信公号‘大雄和你一起学编程’吧");
                return false;
            }
        } finally {
            // 写到finally,保证释放锁
            lock.unlock();
        }
    }
}

results matching ""

    No results matching ""