文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

AndroidLock锁实现原理详细分析

2023-02-17 12:02

关注

Lock简介

Lock接口位于J.U.C下locks包内,其定义了Lock应该具备的方法。

Lock 方法签名:

synchronized和lock的区别

写个Demo

static Lock lock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {         lock.lock();//其他没拿到锁的卡住不动         Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("start to get lock Interruptibly");
                lock.unlock(); //看看会发生什么,注释掉再看看
                lock.lock();
                System.out.println("拿到锁");
                lock.unlock();
                System.out.println("释放锁");
            }
        });
        thread.start();         Thread.sleep(3000);
        lock.unlock();
    }

我们自己来手写一下lock接口的tryLock()、lock()和unLock()方法,实现我们自己的myLock。

public class MyLock implements Lock {
    //多并发调用  0-未占用 大于0-占用
    AtomicInteger state = new AtomicInteger();     Thread ownerThread = new Thread();     //等待锁的队列
    LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue();     @Override
    public void lock() {
        if (!tryLock()) {  //先抢锁,所以是非公平锁
            //没拿到锁,放到队列中去进行排队
            waiters.add(Thread.currentThread());
            //等待被唤醒
            for (; ; ) {
                if (tryLock()) {  //非公平锁情况下,唤醒过来继续获取锁
                    waiters.poll(); //获取锁成功把自己从队列中取出来
                    return;
                } else    //获取锁失败
                    LockSupport.park();  //线程阻塞
            }
        }
    }     @Override
    public boolean tryLock() {
        if (state.get() == 0) { //如果锁没被占用
            if (state.compareAndSet(0, 1)) {  //如果成功拿到锁
                ownerThread = Thread.currentThread();   //占用锁线程改为当前线程
                return true;
            }
        }
        return false;
    }     @Override
    public void unlock() {         if (ownerThread != Thread.currentThread())  //占用锁线程不是当前线程无法释放锁
            throw new RuntimeException("非法调用,当前锁不属于你");         if (state.decrementAndGet() == 0)  //如果成功释放锁
            ownerThread = null;  //占用锁线程置空
        //通知其他线程
//        Thread thread = null;
//
//        while ((thread = waiters.peek()) != null)
//            LockSupport.unpark(thread);
        Thread thread = waiters.peek(); //获取队列头部线程,线程还留在队列中
        if (thread != null) {
            LockSupport.unpark(thread); //取消阻塞
        }
    }     @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return false;
    }     @Override
    public Condition newCondition() {
        return null;
    }     @Override
    public void lockInterruptibly() throws InterruptedException {     }
}

几个注意点:

Lock默认是非公平锁,上面实现的也是非公平锁,小伙伴们可以试一试。

公平锁和非公平锁区别:

先等待先获取锁是公平锁;先等待也不一定先获取锁,可能被突然到来的线程获取到是非公平锁;

公平锁的实现:

  @Override
    public void lock() {
       checkQueue();//线程来的时候先不获取锁,而是先检查队列中有没有等待的线程,如果有,直接放入队列,如果没有,再去获取锁
        if (!tryLock()) {  //先抢锁,所以是非公平锁
            //没拿到锁,放到队列中去进行排队
            waiters.add(Thread.currentThread());
            //等待被唤醒
            for (; ; ) {
                if (tryLock()) {  //非公平锁情况下,唤醒过来继续获取锁
                    waiters.poll(); //获取锁成功把自己从队列中取出来
                    return;
                } else    //获取锁失败
                    LockSupport.park();  //线程阻塞
            }
        }
    }

lock源码

在阅读源码的成长的过程中,有很多人会遇到很多困难,一个是源码太多,另一方面是源码看不懂。在阅读源码方面,我提供一些个人的建议:

接下来进入阅读lock的源码部分,在lock的接口中,主要的方法如下:

public interface Lock {
    // 加锁
    void lock();
    // 尝试获取锁
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    // 解锁
    void unlock();
}

在lock接口的实现类中,最主要的就是ReentrantLock,来看看ReentrantLocklock()方法的源码:

    // 默认构造方法,非公平锁
    public ReentrantLock() {
        sync = new NonfairSync();
    }
    // 构造方法,公平锁
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }
    // 加锁
    public void lock() {
        sync.lock();
    }

在初始化lock实例对象的时候,可以提供一个boolean的参数,也可以不提供该参数。提供该参数就是公平锁,不提供该参数就是非公平锁。

总结

到此这篇关于Android Lock锁实现原理详细分析的文章就介绍到这了,更多相关Android Lock锁内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯