zoukankan      html  css  js  c++  java
  • 手写一把锁Lock,实现一些核心的功能。

    模仿ReentrantLock,来手写一把锁。

    先上版本一。

    package com.itbac.lock;
    
    import java.util.Iterator;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.atomic.AtomicReference;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.LockSupport;
    
    /**
     * 手写一把锁
     */
    public class BacLock implements Lock {
        /**
         * 独占资源所有者
         */
        volatile AtomicReference<Thread> owner = new AtomicReference<>();
        /**
         * 等待的线程
         */
        volatile LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue<>();
    
    
        @Override
        public void lock() {
            //尝试获取锁失败,进入循环
            while (!this.tryLock()) {
                //添加数据到等待队列
                waiters.offer(Thread.currentThread());
                //线程等待
                LockSupport.park();
                //线程被唤醒后,从等待集合中移除
                waiters.remove(Thread.currentThread());
            }
        }
    
        @Override
        public void lockInterruptibly() throws InterruptedException {
    
        }
    
        /**
         * 尝试获取一次锁
         * @return
         */
        @Override
        public boolean tryLock() {
            //CAS,比较和设置
            if (owner.compareAndSet(null, Thread.currentThread())) {
                return true;
            }
            return false;
        }
    
        @Override
        public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
            return false;
        }
    
        @Override
        public void unlock() {
            //释放锁成功
            if (owner.compareAndSet(Thread.currentThread(), null)) {
                //迭代等待者并唤醒等待线程
                Iterator<Thread> iterator = waiters.iterator();
                while (iterator.hasNext()) {
                    Thread next = iterator.next();
                    if (null != next) {
                        //唤醒线程
                        LockSupport.unpark(next);
                    }
                }
            }
    
        }
    
        @Override
        public Condition newCondition() {
            return null;
        }
    }

    上面的代码完成了加锁和释放锁的功能。

    然后我们需要模仿ReentrantLock ,抽象出一个AQS、

    版本二:

    AQS

    package com.itbac.lock;
    
    import java.util.Iterator;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.atomic.AtomicReference;
    import java.util.concurrent.locks.LockSupport;
    
    public abstract class BacAQS {
        /**
         * 独占资源所有者
         */
        volatile AtomicReference<Thread> owner = new AtomicReference<>();
        /**
         * 等待的线程
         */
        volatile LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue<>();
    
        public BacAQS() {
        }
    
        public BacAQS(AtomicReference<Thread> owner, LinkedBlockingQueue<Thread> waiters) {
            this.owner = owner;
            this.waiters = waiters;
        }
    
        public boolean tryAcquire() { // 交给使用者去实现。 模板方法设计模式
            //不支持的操作异常
            throw new UnsupportedOperationException();
        }
    
        public boolean tryRelease() {
            throw new UnsupportedOperationException();
        }
    
        public void acquire(){
            //尝试获取锁失败,进入循环
            while (!this.tryAcquire()) {
                //添加数据到等待队列
                waiters.offer(Thread.currentThread());
                //线程等待
                LockSupport.park();
                //线程被唤醒后,从等待集合中移除
                waiters.remove(Thread.currentThread());
            }
        }
    
        public void release(){
            //释放锁成功
            if (tryRelease()) {
                //迭代等待者并唤醒等待线程
                Iterator<Thread> iterator = waiters.iterator();
                while (iterator.hasNext()) {
                    Thread next = iterator.next();
                    if (null != next) {
                        //唤醒线程
                        LockSupport.unpark(next);
                    }
                }
            }
        }
    
    }

    手写lock

    package com.itbac.lock;
    
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    
    /**
     * 手写一把锁
     */
    public class BacLock implements Lock {
    
        //私有属性
        private BacAQS aqs = new BacAQS() {
            //重写 具体实现逻辑
            @Override
            public boolean tryAcquire() {
                return owner.compareAndSet(null, Thread.currentThread());
            }
    
            @Override
            public boolean tryRelease() {
                return owner.compareAndSet(Thread.currentThread(), null);
            }
        };
        //加锁
        @Override
        public void lock() {
            aqs.acquire();
        }
        /**
         * 尝试获取一次锁
         * @return
         */
        @Override
        public boolean tryLock() {
            return aqs.tryAcquire();
        }
        //释放锁
        @Override
        public void unlock() {
            aqs.release();
        }
    
    
    
        @Override
        public void lockInterruptibly() throws InterruptedException {
        }
        @Override
        public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
            return false;
        }
        @Override
        public Condition newCondition() {
            return null;
        }
    }

    先这样了。

  • 相关阅读:
    Log4j日志
    Spring和MyBatis环境整合
    Hibernatede的优缺点,Struts的工作流程,延迟加载及理解开闭原则
    Java开发中的23种设计模式
    Spring配置
    Spring框架的一些基础知识
    python打造多线程图片下载工具
    redis 主从备份服务器集群搭建
    mongoo数据库设置权限
    mongo数据库主从备份服务集群搭建
  • 原文地址:https://www.cnblogs.com/itbac/p/11901947.html
Copyright © 2011-2022 走看看