zoukankan      html  css  js  c++  java
  • 重入锁简介

    重入锁也叫作递归锁,指的是同一个线程外层函数获取到一把锁后,内层函数同样具有这把锁的控制权限
                synchronized和ReentrantLock就是重入锁对应的实现
                synchronized——重量级的锁         
                ReentrantLock——轻量级的锁         lock()代表加入锁              unlock()代表释放锁
                
                不可重入锁:说明当没有释放该锁时。其他线程获取该锁会进行等待

                    public class MyLock {
                        //标识锁是否可用  如果值为true代表当前有线程正在使用该锁,如果为false代表没有人用锁
                        private boolean isLocked=false;
                        //获取锁:加锁
                        public synchronized void lock() throws InterruptedException {
                            //判断当前该锁是否正在使用
                            while (isLocked){
                                wait();
                            }
                            //当前没有人使用情况下就占用该锁
                            isLocked=true;
                        }
                        //释放锁
                        public synchronized void unLock(){
                            //将当前锁资源释放
                            isLocked=false;
                            //唤起正在等待使用锁的线程
                            notify();
                        }
                    }
                    public class MyLockTest {
                        MyLock myLock=new MyLock();
                        //A业务方法
                        public void print() throws InterruptedException {
                            //获取一把锁
                            myLock.lock();
                            System.out.println("print业务方法");
                            doAdd();
                            //释放锁
                            myLock.unLock();
                        }
    
                        //B业务方法
                        public void doAdd() throws InterruptedException {
                            //获取一把锁
                            myLock.lock();
                            System.out.println("doAdd业务方法");
                            //释放锁
                            myLock.unLock();
                        }
    
                        public static void main(String[] args) throws InterruptedException {
                            MyLockTest test=new MyLockTest();
                            test.print();
                        }
                    }


                
                synchronized可重入性:如果当前A持有一把锁,在A业务内部调用B,那么B也同样拥有这把锁的使用权限

                    public class MyLockTest {
                        //A业务方法
                        public synchronized void print() throws InterruptedException {
                            //获取了一把锁
                            System.out.println("print业务方法");
    
                            doAdd();
    
                        }
    
                        //B业务方法
                        public synchronized void doAdd() throws InterruptedException {
                            System.out.println("doAdd业务方法");
                            //释放锁
                        }
    
                        public static void main(String[] args) throws InterruptedException {
                            MyLockTest test=new MyLockTest();
                            test.print();
                        }
                    }


                
                ReentrantLock同样具有可重入性

                    public class MyLockTest {
                        //创建锁对象
                        Lock lock=new ReentrantLock();
                        //A业务方法
                        public  void print() throws InterruptedException {
                            //获取了一把锁
                            lock.lock();
                            System.out.println("print业务方法");
                            doAdd();
                            //释放锁
                            lock.unlock();
                        }
    
                        //B业务方法
                        public  void doAdd() throws InterruptedException {
                            //获取了一把锁
                            lock.lock();
                            System.out.println("doAdd业务方法");
                            //释放锁
                            lock.unlock();
                        }
    
                        public static void main(String[] args) throws InterruptedException {
                            MyLockTest test=new MyLockTest();
                            test.print();
                        }
                    }


                
                
                ReentrantLock底层:

                    public ReentrantLock() {
                        //默认非公平锁
                        sync = new NonfairSync();
                    }
                    
                    public ReentrantLock(boolean fair) {
                        //如果为true代表公平锁,否则为非公平锁
                        sync = fair ? new FairSync() : new NonfairSync();
                    }
                    
                    
                    public class MyReentrantLock {
                        //标识锁是否可用  如果值为true代表当前有线程正在使用该锁,如果为false代表没有人用锁
                        private boolean isLocked=false;
                        //当前线程
                        Thread lockedBy=null;
                        //加锁数量计数
                        Integer lockedCount=0;
                        //加锁
                        public synchronized void lock() throws InterruptedException {
                            //获取当前线程
                            Thread thread=Thread.currentThread();
                            //判断当前是否正在使用锁,如果正在使用则对比当前使用要使用锁的线程和之前使用锁的线程是否一致
                            //如果一致代表可以重入,继续使用锁,不会发生阻塞
                            //如果不一致代表当前不是一个线程,则等待
                            while (isLocked && thread!=lockedBy){
                                wait();
                            }
                            //占用锁
                            isLocked=true;
                            //计数+1
                            lockedCount++;
                            //赋值线程
                            lockedBy=thread;
                        }
                        //释放锁
                        public synchronized void unlock(){
                            //判断当前是否是用一个线程
                            if(Thread.currentThread()==this.lockedBy){
                                //锁使用计数器-1
                                lockedCount--;
                                //判断计数器是否为0,如果为0则释放锁,然后唤醒正在等待的线程
                                if(lockedCount==0){
                                    isLocked=false;
                                    notify();
                                }
                            }
                        }
                    }
  • 相关阅读:
    一个接口的性能问题定位和分析过程
    HTTP请求全过程(很全面)
    Linux中查看物理CPU个数、核数、逻辑CPU个数
    linux查看文件大小
    ping不通判断系统是否开机
    ping不通判断系统是否开机
    linux压缩解压文件命令
    python连接redis集群,添加数据
    初学python
    企业级BI为什么这么难做?
  • 原文地址:https://www.cnblogs.com/chx9832/p/12566762.html
Copyright © 2011-2022 走看看