• ReentrantLock和synchronized总结


    一、简介
    ReentrantLock常常对比着synchronized来分析,我们先对比着来看然后再一点一点分析。
    (1)synchronized是独占锁,加锁和解锁的过程自动进行,易于操作,但不够灵活。ReentrantLock也是独占锁,加锁和解锁的过程需要手动进行,不易操作,但非常灵活。
    (2)synchronized可重入,因为加锁和解锁自动进行,不必担心最后是否释放锁;ReentrantLock也可重入,但加锁和解锁需要手动进行,且次数需一样,否则其他线程无法获得锁。
    (3)synchronized不可响应中断,一个线程获取不到锁就一直等着;ReentrantLock可以相应中断。
    ReentrantLock好像比synchronized关键字没好太多,我们再去看看synchronized所没有的,一个最主要的就是ReentrantLock还可以实现公平锁机制。什么叫公平锁呢?也就是在锁上等待时间最长的线程将获得锁的使用权。通俗的理解就是谁排队时间最长谁先执行获取锁。

    二: ReentrantLock相比synchronized的额外功能

    公平锁是指当锁可用时,在锁上等待时间最长的线程将获得锁的使用权。而非公平锁则随机分配这种使用权。和synchronized一样,默认的ReentrantLock实现是非公平锁,因为相比公平锁,非公平锁性能更好。当然公平锁能防止饥饿,某些情况下也很有用。在创建ReentrantLock的时候通过传进参数true创建公平锁,如果传入的是false或没传参数则创建的是非公平锁

    static Lock lock = new ReentrantLock(true);

    代码如下所示:

    public class ReentrantLockTest {
    
        static Lock lock = new ReentrantLock(true);
    
        public static void main(String[] args) throws InterruptedException {
            for(int i=0;i<5;i++){
                new Thread(new ThreadDemo(i)).start();
            }
        }
    
        static class ThreadDemo implements Runnable {
    Integer id;
    public ThreadDemo(Integer id) { this.id = id; } @Override public void run() { try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } for(int i=0;i<2;i++){ lock.lock(); System.out.println("获得锁的线程:"+id); lock.unlock(); } } } }

    运行结果如下所示:

    获得锁的线程:4
    获得锁的线程:1
    获得锁的线程:2
    获得锁的线程:0
    获得锁的线程:3
    获得锁的线程:4
    获得锁的线程:1
    获得锁的线程:2
    获得锁的线程:0
    获得锁的线程:3

    非公平锁运行结果如下所示:

    获得锁的线程:1
    获得锁的线程:1
    获得锁的线程:2
    获得锁的线程:2
    获得锁的线程:3
    获得锁的线程:3
    获得锁的线程:4
    获得锁的线程:0
    获得锁的线程:0
    获得锁的线程:4

    线程会重复获取锁。如果申请获取锁的线程足够多,那么可能会造成某些线程长时间得不到锁。这就是非公平锁的“饥饿”问题。
    公平锁和非公平锁该如何选择:
    大部分情况下我们使用非公平锁,因为其性能比公平锁好很多。但是公平锁能够避免线程饥饿,某些情况下也很有用。

  • 相关阅读:
    重构SWF为fla文件三
    重构SWF为fla文件四
    SQL Server中删除重复数据的几个方法
    重构SWF为fla文件五
    重构SWF为fla文件六
    MySQL下载与安装
    C++根据.h文件批量生成需要的函数框架
    pku acm 2362 square 解题报告
    Ackerman 函数的解法
    Web.Config 的读写
  • 原文地址:https://www.cnblogs.com/jelly12345/p/12446902.html
Copyright © 2020-2023  润新知