知识整理|锁

1. ReentrantLock

1.1 ReentrantLock VS. synchronized

  • ReentrantLock相比synchronized而言功能更加丰富,使用起来更为灵活,也更适合复杂的并发场景
  • 都是独占锁
  • 都是可重入的,synchronized因此可以放在递归中,而重入锁需要保证加锁和解锁次数一样

1.2 创建公平锁

// 传入true 创建公平锁
ReentrantLock lock = new ReentrantLock(true);

参考资料:ReentrantLock(重入锁)功能详解和应用演示

1.3 响应中断

  • lockInterruptibly():可以响应中断的取锁方法
  • Thread#interrupt():线程中断
public class ReentrantLockTest {
    static Lock lock1 = new ReentrantLock();
    static Lock lock2 = new ReentrantLock();
    public static void main(String[] args) throws InterruptedException {

        Thread thread = new Thread(new ThreadDemo(lock1, lock2));//该线程先获取锁1,再获取锁2
        Thread thread1 = new Thread(new ThreadDemo(lock2, lock1));//该线程先获取锁2,再获取锁1
        thread.start();
        thread1.start();
        thread.interrupt();//是第一个线程中断
    }

    static class ThreadDemo implements Runnable {
        Lock firstLock;
        Lock secondLock;
        public ThreadDemo(Lock firstLock, Lock secondLock) {
            this.firstLock = firstLock;
            this.secondLock = secondLock;
        }
        @Override
        public void run() {
            try {
                firstLock.lockInterruptibly();
                TimeUnit.MILLISECONDS.sleep(10);//更好的触发死锁
                secondLock.lockInterruptibly();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                firstLock.unlock();
                secondLock.unlock();
                System.out.println(Thread.currentThread().getName()+"正常结束!");
            }
        }
    }
}

1.4 获取锁时限时等待

  • ReentrantLock#tryLock():可以选择传入时间参数,表示等待指定的时间,无参则表示立即返回锁申请的结果:true表示获取锁成功,false表示获取锁失败
  • 可以用来解决死锁问题

2. 公平锁/非公平锁

公平锁:在锁可用时,在锁上等待时间最长的线程获得锁
非公平锁:随机分配这种使用权

  • 公平锁就是在获取锁之前会先用hasQueuedPredecessors判断等待队列是否为空或者自己是否位于队列头部,该条件通过才能继续获取锁。
  • 非公平锁公平锁性能更好,公平锁能够防止饥饿
公平锁和非公平锁

参考资料:一张图读懂非公平锁与公平锁

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。