Java手写自己的lock

 

基础:需要熟悉JUC工具包以及底层的cas原理和AQS

接下来我们正入主题

第一种最简单的方法,使用工具类来实现简单的同步

我们可以使用AtomicReference来操作当前,当然也可以使用semaphore,阻塞队列等,这样可以实现简单的锁,达到同步的效果。

public class AbleLock {
    //新建一个原子引用类,负责操作当前线程
    AtomicReference<Thread> reference=new AtomicReference<Thread>();
    Thread thread=null;
    public void lock() {
        //获取当前的线程,如果是空的话,则进行cas操作
        thread = Thread.currentThread();
        if (reference.get() == null) {
            reference.compareAndSet(null, thread);
        }
    }
    public void unlock(){
        //这里没有使用cas设置为null,原因是刚开始是很多线程同时在争抢,
        //而拿到资源的线程只有一个,所以不必使用cas操作
        reference.set(null);
    }
}

接下来我们测试一下

public class TestLock {
    int count=0;
    AbleLock lock=new AbleLock();
    public void add() {
        lock.lock();
        count++;
        lock.unlock();
    }
    public int getCount(){
        return count;
    }

    public static void main(String[] args) throws InterruptedException {
        TestLock testLock=new TestLock();

        for(int i=0;i<2000;i++){
            Thread thread=new Thread(()->{
                for(int j=0;j<500;j++){
                    testLock.add();
                }
            });
            thread.start();
            //先让其他的线程执行,最后主线程再输出count的值
            thread.join();
        }


        System.out.println("count的值是"+testLock.getCount());
    }
}

可以看出我们的结果已经达到了,但是这样的锁功能没有那么强大,只能实现简单的同步,不可重入,太多缺陷

第二种就是通过实现lock接口,定义一个内部类,通过继承AQS(AbstractQueuedSynchronizer)类达到排它锁,这里涉及到了模板设计模式

内部类继承AQS后,需要重写这几个方法

isHeldExclusively()
tryAcquire(int arg)
tryRelease(int arg)

 

public class SelfLock implements Lock {

    private  static class Sync extends AbstractQueuedSynchronizer{
        //state 表示是否处于占用,1为占用,0为没有
        //当前锁是否处于占用
        @Override
        protected boolean isHeldExclusively() {
            return getState()==1;
        }

        @Override
        protected boolean tryAcquire(int arg) {
            if(compareAndSetState(0,1)){
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        @Override
        protected boolean tryRelease(int arg) {
            if(getState()==0){
                throw  new  UnsupportedOperationException();
            }
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }
        public Condition newCondition() {
            return new ConditionObject();
        }
    }
    private Sync sync=new Sync();
    @Override
    public void lock() {
        sync.acquire(1);
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }

    @Override
    public boolean tryLock() {
       return sync.tryAcquire(1);
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return sync.tryAcquireNanos(1,unit.toNanos(time));
    }

    @Override
    public void unlock() {
        sync.release(1);
    }

    @Override
    public Condition newCondition() {
        return sync.newCondition();
    }
}

这样也就实现了锁的效果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值