• 手写Lockl锁


    可分为三步:

      1.实现Lock类;

      2.实现lock()

      3.实现unlock()

      

    以下图形象的表示抢锁与释放锁过程

      

    相关代码如下:

    package myLock;
    
    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;
    
    /**
     * 简单描述
     *
     * @author lijie
     * @data 2021/5/11 22:17
     */
    public class JieLock implements Lock {
        // 房卡,用来登记线程
        AtomicReference<Thread> owners = new AtomicReference<>();
        // 队列(此队列安全+高效)。用来存放没有抢到锁的线程
        LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue<>();
    
        @Override
        public void lock() {
            while (!owners.compareAndSet(null, Thread.currentThread())) {
                // 若抢不到锁,则等待
                waiters.add(Thread.currentThread());
                // 让当前线程阻塞
                LockSupport.park();
                // 当不阻塞时,从队列中将该线程移除
                waiters.remove(Thread.currentThread());
            }
    
        }
    
        @Override
        public void lockInterruptibly() throws InterruptedException {
    
        }
    
        @Override
        public boolean tryLock() {
            return false;
        }
    
        @Override
        public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
            return false;
        }
    
        @Override
        public void unlock() {
            // 只有持有锁的线程才可以释放锁
            if (owners.compareAndSet(Thread.currentThread(), null)) {
                for (Thread waiter : waiters) {
                    LockSupport.unpark(waiter);
                }
            } else {
            }
        }
    
        @Override
        public Condition newCondition() {
            return null;
        }
    }

    进行测试:

      

    package myLock;
    
    /**
     * 简单描述
     *
     * @author lijie
     * @data 2021/5/11 22:35
     */
    public class TestLock {
        int i = 10000;
        JieLock lock = new JieLock();
        public void order(){
            lock.lock();
            try {
                i--;
            } finally {
                lock.unlock();
    
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
            TestLock lock1 = new TestLock();
            for (int i = 0; i < 10; i++) {
                new Thread(()->{
                    for (int j = 0; j < 1000; j++) {
                        lock1.order();
                    }
                }).start();
            }
            // 等待线程执行完操作
            Thread.sleep(2000);
            System.out.println(lock1.i);
        }
    
    }
  • 相关阅读:
    PHP学习当中遗漏的知识点
    sql必知必会(第四版) 学习笔记
    servlet 笔记
    sql server 快捷键
    233
    第 四 课 数据类型
    第三课 go语言基础语法
    第二课 go语言的结构
    第 1 课 Go 简介
    linux 学习 查看文件占用空间大小
  • 原文地址:https://www.cnblogs.com/codehero/p/14757889.html
Copyright © 2020-2023  润新知