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();
                                }
                            }
                        }
                    }
  • 相关阅读:
    界面控件DevExpress WPF入门 表达式编辑器功能
    Telerik UI for WPF全新版本——拥有Office2019高对比度主题
    DevExpress报表控件v21.2 全新的Visual Studio报表设计器
    报告生成器FastReport .NET入门指南 在Linux中启动应用程序
    文档控件DevExpress Office File API v21.2 自定义字体加载引擎
    UI组件库Kendo UI for Angular入门 如何开始使用图表功能
    WPF界面工具Telerik UI for WPF入门级教程 设置一个主题(二)
    DevExtreme初级入门教程(React篇) TypeScript支持
    报表开发利器FastReport .NET v2022.1 添加关键对象和属性
    python项目打包(一) setup.py、Python源代码项目结构
  • 原文地址:https://www.cnblogs.com/chx9832/p/12566762.html
Copyright © 2011-2022 走看看