zoukankan      html  css  js  c++  java
  • 一、锁

    锁的实现有两种,一种是用synchronized关键字,另一种是lock接口,显示的加锁解锁。

    二、synchronized关键字加锁:

    锁——synchronized

    三、lock接口加锁

     在jdk 5之后,并发包中新增了Lock接口及相关实现类来实现锁功能。

     Lock接口和synchronized关键字实现锁的区别:

    (1)Lock接口需要显示的获取和释放锁,sychronized是隐式的获取和释放锁。也正因为如此,使得Lock接口拥有了锁获取与释放的可操作性、可中断的获取锁、超时获取锁 等多种synchronized关键字所不具备的同步特性。

    例如:一个场景,先获取锁A,然后获取锁B,当B获得后,同时释放A,同时获取锁C。以此类推。这种场景synchronized就不好实现了。

    (2)尝试非阻塞的获取锁:当前线程尝试获取锁,若这一时刻没有其他线程获取到该锁,则成功获取并持有锁。

    (3)能被中断的获取:获取到锁的线程能够 响应中断,当获取到锁的线程被中断时,中断异常将会被抛出,同时锁会被释放。

    (4)超时获取锁:在指定的截止时间之前获取锁,如果截止时间到了仍旧无法获取锁,则返回。

    Lock lock = new ReentrantLock();
    lock.lock;
    try{
    }finally{
        lock.unlock();  
    }

    2、Lock接口常用API

    ReentrantLock重入锁

    1、ReentrantLock:支持重进入的锁,即:能够支持一个线程对资源的重复加锁。此外该锁还支持获取锁时的公平和非公平性选择,默认是非公平锁。

      ReentrantLock在调用lock()方法时,已经获取到锁的线程,能够再次调用lock()方法获取锁,而不被阻塞。

      synchronize实现的是隐式的重入锁,reentrantLock是显示的,见上一句。

    补充:

    锁的公平性:公平性是针对获取锁而言的,如果一个锁是公平的,那么锁的获取顺序就应该符合请求的绝对时间顺序,就是FIFO。

         非公平锁可能使线程“饥饿”,但是极少的线程切换,保证了其更大的吞吐量;而公平锁需要进行大量的线程切换,这就是保证FIFO的代价。

    2、实现机制:主要解决了两个问题,线程再次获取锁,锁的最终释放。

    (1)线程再次获取锁:锁需识别获取锁的线程是否是当前线程,若是当前线程,则再次成功获取。

    (2)锁的最终释放:线程重复n次获取了锁,随后在第n次释放该锁后,其他线程能够获取到该锁。锁的最终释放要求锁对于获取进行计数自增,计数表示当前锁被重复获取的次数,而锁被释放时,计数自减,当计数等于0时表示锁已经成功释放。

    四、Synchronized 和 ReentrantLock的区别:

    1、相同点:

    (1)都是用来协调多线程对共享对象、变量的访问。即防止多个线程同时访问共享资源。

    (2)都是可重入锁,同一线程可以多次获得同一个锁

    (3)都保证了可见性和互斥性。互斥性就是一个线程得到锁了,其他线程得不到了。

    2、区别:

    (1)ReentrantLock 是 API 级别的,synchronized 是 JVM 级别的。

    (2)ReentrantLock 显示的获得、释放锁,synchronized 隐式获得释放锁。

    (3)ReentrantLock 可以实现公平锁,ReentrantLock 提供了构造器,能够控制锁是否公平,即FIFO谁先来的,谁先获得锁,获取锁的时候排队。

    (4)synchronized 在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而 Lock 在发生异常时,如果没有主动通过 unLock()去释放锁,则很可能造成死锁现象,因此使用 Lock 时需要在 finally 块中释放锁。

    (5)Lock 可以让等待锁的线程响应中断,即在获取锁的过程中可以中断当前线程,而 synchronized 却不行,使用 synchronized 时,等待的线程会一直等待下去,不能够响应中断。

    (6)通过 Lock 可以知道有没有成功获取锁,而 synchronized 却无法办到。

    (7) Lock 可以提高多个线程进行读操作的效率,既就是实现读写锁等。

    (8)Lock 是一个接口,而 synchronized 是 Java 中的关键字,synchronized 是内置的语言实现。

    (9) ReentrantLock 通过 Condition 可以绑定多个条件

    (10)底层实现不一样, synchronized 是同步阻塞,使用的是悲观并发策略,lock 是同步非阻塞,采用的是乐观并发策略

  • 相关阅读:
    使用 Dockerfile 定制镜像
    UVA 10298 Power Strings 字符串的幂(KMP,最小循环节)
    UVA 11090 Going in Cycle!! 环平均权值(bellman-ford,spfa,二分)
    LeetCode Best Time to Buy and Sell Stock 买卖股票的最佳时机 (DP)
    LeetCode Number of Islands 岛的数量(DFS,BFS)
    LeetCode Triangle 三角形(最短路)
    LeetCode Swap Nodes in Pairs 交换结点对(单链表)
    LeetCode Find Minimum in Rotated Sorted Array 旋转序列找最小值(二分查找)
    HDU 5312 Sequence (规律题)
    LeetCode Letter Combinations of a Phone Number 电话号码组合
  • 原文地址:https://www.cnblogs.com/guoyu1/p/12179117.html
Copyright © 2011-2022 走看看