zoukankan      html  css  js  c++  java
  • 公平锁与非公平锁

    公平锁与非公平锁

    # 公平锁与非公平锁
    公平锁:
    多个线程按照申请锁的顺序来获取锁,先来后到,在并发环境中,每个线程在获取锁时会先查看此锁维护的等待队列,如果为空,或者当前线程等待队列的第一个,就占有锁,否则就会加入到等待队列,以后会按照FIFO的规则从队列中取。
    非公平锁:
    多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程获取锁。在高并发的情况下,哟可能会造成优先级反转或者饥饿现象。

    ReentrantLock类 :默认是非公平锁,在构造函数中加参数true,会创建公平锁。

    非公平锁的优点:非公平锁的吞吐量大

    ReentrantLock的构造器,默认时new 一个非公平的锁。

     非公平锁有哪几种ReentrantLock,synchronized


     可重入锁,也叫递归锁

     可重入锁:指的是同一个线程外层函数获得锁之后,内层递归函数仍然能获取该锁的代码,在同一个线程在外层方法获取锁的时候,进入内层方法会自动获取锁  

     种类:ReentrantLock 和 synchronized 都是可重入锁 

     作用:避免死锁 

    注意点:用了锁,一定要记得开锁和关锁,lock和unlock方法都是一对一对的出现,避免出现错误,如果少了其中的一个,就会报错。

    ReentrantLock  版本:

    public class MyLock_1 {
        
        public static void main(String[] args) {
            Mylock(); 
            new Thread(()->{
                Mylock();
            }).start();
        }
    
       static ReentrantLock reentrantLock = new ReentrantLock();
        public static void Mylock(){
            reentrantLock.lock();
            try {
                System.out.println("第一把锁:"+Thread.currentThread().getId());
                Lock lock = new ReentrantLock();
                lock.lock();
                try {
                    System.out.println("第二把锁:"+Thread.currentThread().getId());
                }finally {
                    lock.unlock();
                }
            }catch (Exception ex){
                ex.printStackTrace();
            }finally {
                reentrantLock.unlock();
            }
        }
    }
    结果:
    synchronized 版本:其实一层里面再套一层,多层,但是获取到的对象都是第一把锁,锁住的对象。
    public class Xttblog {
        public static void main(String[] args) {
            Xttblog child = new Xttblog();
            child.doSomething();
        }
     
        public synchronized void doSomething() {
            System.out.println("child.doSomething()" + Thread.currentThread().getName());
            doAnotherThing(); // 调用自己类中其他的synchronized方法
        }
     
        private synchronized void doAnotherThing() {
            super.doSomething(); // 调用父类的synchronized方法
            System.out.println("child.doAnotherThing()" + Thread.currentThread().getName());
        }
    }
     
    class SuperXttblog {
        public synchronized void doSomething() {
            System.out.println("father.doSomething()" + Thread.currentThread().getName());
        }
    }

    结果:

     可重入锁的原理: 详情到时看 ReentrantLock 源码 

    重入锁实现可重入性原理或机制是:每一个锁关联一个线程持有者和计数器,当计数器为 0 时表示该锁没有被任何线程持有,那么任何线程都可能获得该锁而调用相应的方法;

    当某一线程请求成功后,JVM会记下锁的持有线程,并且将计数器置为 1;此时其它线程请求该锁,则必须等待;而该持有锁的线程如果再次请求这个锁,就可以再次拿到这个锁,

    同时计数器会递增;当线程退出同步代码块时,计数器会递减,如果计数器为 0,则释放该锁。

  • 相关阅读:
    Web API 强势入门指南
    毫秒必争,前端网页性能最佳实践
    Windbg Extension NetExt 使用指南 【3】 ---- 挖掘你想要的数据 Managed Heap
    Windbg Extension NetExt 使用指南 【2】 ---- NetExt 的基本命令介绍
    Windbg Extension NetExt 使用指南 【1】 ---- NetExt 介绍
    WCF : 修复 Security settings for this service require Windows Authentication but it is not enabled for the IIS application that hosts this service 问题
    透过WinDBG的视角看String
    Microsoft Azure Web Sites应用与实践【4】—— Microsoft Azure网站的“后门”
    企业IT管理员IE11升级指南【17】—— F12 开发者工具
    WCF : 如何将NetTcpBinding寄宿在IIS7上
  • 原文地址:https://www.cnblogs.com/cb1186512739/p/12743252.html
Copyright © 2011-2022 走看看