首页 > 其他 > 详细

手写Lock

时间:2020-05-23 18:28:20      阅读:52      评论:0      收藏:0      [点我收藏+]
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;

public class MyLock implements Lock {

    // 锁的状态 0 - 未占用 1 - 占用
    AtomicInteger state = new AtomicInteger();
    // 当前占用的线程
    Thread ownerThread = null;
    // 当前等待抢锁的线程
    LinkedBlockingDeque<Thread> waiters = new LinkedBlockingDeque<>();

    @Override
    public void lock() {
        if (!tryLock()) {
            waiters.add(Thread.currentThread()); // 1. 先排队
            for (;;) {
                if (tryLock()) {
                    // 如果某一个线程抢到了锁,自己把自己从队列里面挪出来
                    waiters.poll();
                    return;
                } else {
                    LockSupport.park(); // 2. 等呗 -- 等待到何时再执行?唤醒目的是继续抢锁
                }
            }
        }

    }

    @Override
    public void unlock() {
        if (ownerThread != Thread.currentThread()) {
            throw new RuntimeException("非法调用---当前这个锁不属于你");
        }
        if (state.decrementAndGet() == 0) { //减1等0 - 0代表锁未被占用
            ownerThread = null;
            // 通知其他正在等待的线程
            Thread waiterThread = waiters.peek();// 取出队列的第一个(但队列中仍然存在)FIFO先进先出
            LockSupport.unpark(waiterThread);
        }

    }

    @Override
    public boolean tryLock() {
        // 把 0 - 1
        if (state.get() == 0) {
            // CAS 底层c++实现 保证N个线程同事操作,只有一个线程操作成功
            if (state.compareAndSet(0, 1)) {
                ownerThread = Thread.currentThread();
                return true;
            }
        }

        return false;
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return false;
    }
    
    @Override
    public Condition newCondition() {
        return null;
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {

    }

}

测试类

import java.util.Date;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockDemo {
//   static Lock lock = new ReentrantLock(); //默认非公平
    static Lock lock = new MyLock();
//  new ReentrantLock(true); 公平锁
    public static void main(String[] args) throws InterruptedException {
        // 主线程获取到锁
        lock.lock(); // 其他没有获取到锁 阻塞 卡住不动
        System.out.println("主线程获取到锁 其他线程卡住不动 " + Thread.currentThread().getName() + new Date());
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                lock.lock();
                System.out.println(Thread.currentThread().getName() + "---获取到锁---");
                lock.unlock();
                System.out.println(Thread.currentThread().getName() + "---释放锁---");
            }
        });
        thread.start();
        // 主线程睡眠3s
        Thread.sleep(3000L);
        lock.unlock();
        System.out.println("3s后主线程释放锁 其他线程可以开始抢锁 " + Thread.currentThread().getName() + new Date());
    }
}

主线程获取到锁 其他线程卡住不动 mainSat May 23 16:48:40 CST 2020
3s后主线程释放锁 其他线程可以开始抢锁 mainSat May 23 16:48:43 CST 2020
Thread-0---子线程获取到锁---
Thread-0---子线程释放锁---



手写Lock

原文:https://www.cnblogs.com/south-pigeon/p/12943319.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!