随手写个互斥锁、共享锁

曾经面试老被人问AQS,其实挺烦人的,我又不是作者,那记得那么多细节。原理我懂,给我个可以保证原子性的工具以及支持等待唤醒的工具,我自己也能实现。包括Redisson它也是利用了Redis的原子性和发布订阅功能来实现。

以下是利用synchronized 保证对state操作的原子性,还有wait/notify 支持等待唤醒实现的互斥锁

package com.example.demo;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MyLock {


    private  int state = 0;

    private long threadId = -1;

    private  final Object object = new Object();
    
    public void lock(){
        while(true){
            if(state != 0) {
                synchronized (object) {
                    if (state != 0) {
                        //未获取到锁
                        try {
                            object.wait();
                        } catch (InterruptedException e) {
                            //TODO 中断响应
                        }

                    }
                }
            }else{
                synchronized (object) {
                    if (state != 0) {
                        //未获取到锁
                        try {
                            object.wait();
                        } catch (InterruptedException e) {
                            //TODO 中断响应
                        }

                    }else{
                        //获取到锁
                        threadId = Thread.currentThread().getId();
                        state += 1;
                        return;
                    }
                }

            }
        }
    }



    public void unlock() {
        if (threadId != Thread.currentThread().getId()) {
            return;
        }

        if (state != 0) {
            synchronized (object) {
                if (state != 0) {
                    //释放成功
                    state -= 1;
                    threadId = -1;
                    object.notify();
                    return;

                }
            }
        }

    }

    public static void main(String[] args) throws InterruptedException {
        testLock();
    }
	//测试无锁 输出是错的 我这边输出是997
    public static void testNoLock() throws InterruptedException {
        ExecutorService es = Executors.newCachedThreadPool();

        int[] arrs = new int[]{0};


        for(int i =0;i<1000;i++){
            es.submit(()->{
                arrs[0] += 1;
            });

        }

        Thread.sleep(10000);
        System.out.println(arrs[0]);

    }
   //测试锁 输出1000
    public static void testLock() throws InterruptedException {
        ExecutorService es = Executors.newCachedThreadPool();

        int[] arrs = new int[]{0};

        MyLock myLock = new MyLock();
        for(int i =0;i<1000;i++){
            es.submit(()->{
                myLock.lock();
                arrs[0] += 1;
                myLock.unlock();
            });

        }

        Thread.sleep(10000);
        System.out.println(arrs[0]);

    }
}

以下是共享锁

package com.example.demo;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MyShareLock {

    private final int maxState;
    private final long[] threadIdList;

    MyShareLock(int maxState){
        this.maxState = maxState;
        this.threadIdList = new long[this.maxState];
    }

    MyShareLock(){
        this(1);
    }

    private  int state = 0;
    private  final Object object = new Object();

    public void lock(){
        while(true){
            if(state == maxState) {
                synchronized (object) {
                    if (state == maxState) {
                        //未获取到锁
                        try {
                            object.wait();
                        } catch (InterruptedException e) {
                            //TODO 中断响应
                        }

                    }
                }
            }else {
                synchronized (object) {
                    if (state == maxState) {
                        //未获取到锁
                        try {
                            object.wait();
                        } catch (InterruptedException e) {
                            //TODO 中断响应
                        }

                    }else{
                        //获取到锁
                        threadIdList[state] =  Thread.currentThread().getId();
                        state += 1;
                        return;
                    }
                }

            }
        }
    }

    private int isHoldThread() {
        synchronized (object) {
            long currentThreadId = Thread.currentThread().getId();

            for (int i = 0; i < threadIdList.length; i++) {
                if (threadIdList[i] == currentThreadId) {
                    return i;
                }

            }
        }
        return -1;
    }


    public void unlock() {
        int index;
        if((index = isHoldThread()) == -1){
            return;
        }

        if (state != 0) {
            synchronized (object) {
                if (state != 0) {
                    //释放成功
                    state -= 1;
                    threadIdList[index] = -1;
                    object.notify();
                    return;

                }
            }
        }

    }

    public static void main(String[] args) throws InterruptedException {
        testLock();
    }

    //测试锁 输出是每10秒以上批量输出一次
    public static void testLock() throws InterruptedException {
        ExecutorService es = Executors.newCachedThreadPool();

        int[] arrs = new int[]{0};

        MyShareLock myShareLock = new MyShareLock(10);
        for(int i =0;i<1000;i++){
            es.submit(()->{
                myShareLock.lock();
                System.out.println(System.currentTimeMillis());
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                myShareLock.unlock();
            });

        }

        Thread.sleep(100000);
        System.out.println(arrs[0]);

    }
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值