1. 什么是Lock锁

Lock是一个接口,其中一个实现类为ReentrantLock,使用lock必须创建它的实现类,也是一个线程同步锁,非公平锁、可重入锁,需要手动释放锁。

2. ReentrantLock和synchronized的区别

特性 synchronized ReentrantLock
可重入锁 支持 支持
是否公平锁 默认否(可选)
锁超时 不支持 支持
锁释放 自动释放 调用unlock()方法释放

3. Lock锁常用的方法

3.1. void lock()

获取锁,如果锁获取不到则线程阻塞,直到锁被释放,线程中断仍继续等待。

3.2. void unlock()

释放锁。

public class LockTest {

    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
        new Thread(()->{
            test1(1, lock);
        }).start();

        new Thread(()->{
            test1(2, lock);
        }).start();

    }

    public static void test1(int a, Lock lock){
        System.out.println(a + "开始获取锁");
        lock.lock();
        System.out.println(a + "获取锁成功");
        try {
            System.out.println(a + "开始执行业务");
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
            System.out.println(a + "释放锁成功");
        }
    }
}

3.3. boolean tryLock()

尝试获取锁,如果能获取到锁则返回true,获取失败则返回false,不会阻塞当前线程。

public class LockTest {

    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
        new Thread(()->{
            test1(1, lock);
        }).start();

        new Thread(()->{
            test1(2, lock);
        }).start();

    }

    public static void test1(int a, Lock lock){
        System.out.println(a +"尝试获取锁");
        boolean tryLock = lock.tryLock();
        System.out.println(a + "获取锁" + (tryLock ? "成功" : "失败"));
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            //只要获取锁成功后才能调用释放锁否则异常
            if (tryLock){
                lock.unlock();
            }
        }
    }
}

3.4. boolean tryLock(long timeout, TimeUnit unit)

在指定的时间内尝试获取锁,在该设定的时间段内,能获取锁到则返回true,获取失败则返回false,不会阻塞当前线程。

public class LockTest {

    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
        new Thread(()->{
            test1(1, lock);
        }).start();

        new Thread(()->{
            test1(2, lock);
        }).start();

    }
	/**
     * 这里尝试3秒内获取锁,业务执行5秒。获取锁失败
     * 如需成功则将3000改为6000
     * @param a
     * @param lock
     */
    public static void test1(int a, Lock lock){
        System.out.println(a +"尝试获取锁");
        boolean tryLock = false;
        try {
            tryLock = lock.tryLock(3000, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(a + "获取锁" + (tryLock ? "成功" : "失败"));
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            //只要获取锁成功后才能调用释放锁否则异常
            if (tryLock){
                lock.unlock();
            }
        }
    }
}

3.6 boolean isFair()

查询锁是否设置为公平的,返回true为公平锁,false为非公平锁。

public class LockTest {
    public static void main(String[] args) {
        //创建一个非公平锁
        ReentrantLock lock1 = new ReentrantLock();
        System.out.println(lock1.isFair());
        //创建公平锁
        ReentrantLock lock2 = new ReentrantLock(true);
        System.out.println(lock2.isFair());
    }
}
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐