显示锁和内置锁

内置锁(Synchronized)优势

  1. 代码简洁
  2. 不会因为没释放锁,导致锁泄露。

显示锁(Lock)优势

  1. 灵活性强,锁的获取可以被中断,可以尝试获取锁。
  2. 读多写少等场景。

用法

能用内置锁就用内置锁,不能用内置锁,才考虑用显示锁。

Lock接口

接口主要方法如下:

  1. lock():获取锁
  2. tryLock():尝试获取锁,true表示未加锁的情况。
  3. unlock():释放锁
  4. newCondition():创建一个Condition

Condition接口

接口主要方法如下:

  1. await():等待,类似wait方法
  2. signal():唤醒,类似notify方法
  3. signalAll():唤醒全部,类似notifAll方法

使用形式

Lock lock = new ReentrantLock();
....
lock.lock();//获取锁
try{
    //业务逻辑
}finally{
    lock.unlock();//这边要注意释放,不然会导致锁泄露
}

示例

public class LockDemo {
    Lock lock = new ReentrantLock();
    static int num = 0;

    public void addNum(int value) {
        lock.lock();
        try {
            int temp = num;
            num = num + value;
            Thread.sleep(100);
            System.out.println(value + "+" + temp + "=" + num);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    static class AddThread1 extends Thread {
        LockDemo lockDemo;

        public AddThread1(LockDemo lockDemo) {
            this.lockDemo = lockDemo;
        }

        @Override
        public void run() {
            lockDemo.addNum(1);
        }
    }

    static class AddThread2 extends Thread {
        LockDemo lockDemo;

        public AddThread2(LockDemo lockDemo) {
            this.lockDemo = lockDemo;
        }

        @Override
        public void run() {
            lockDemo.addNum(2);
        }
    }


    public static void main(String[] args) {
        LockDemo lockDemo = new LockDemo();
        AddThread1 addThread1 = new AddThread1(lockDemo);
        AddThread2 addThread2 = new AddThread2(lockDemo);
        addThread1.start();
        addThread2.start();
    }
}

运行结果如下:
clipboard.png
结果显示,跟之前synchronized结果是一样的,加锁解锁成功

公平锁和非公平锁

  1. 公平锁:先进来的线程先执行
  2. 非公平锁:后进来的线程可能先执行,效率较高。会进行抢锁操作,如果cas获取不到锁,也会进入阻塞队列等到唤醒。

ReentrantLock

构造参数有两个,默认是非公平锁,如果传参是true,则是公平锁。

public ReentrantLock() {
    sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
    sync = fair ? new FairSync() : new NonfairSync();
}

大军
847 声望183 粉丝

学而不思则罔,思而不学则殆