首页 > 编程语言 >并发编程(ReentrantLock)

并发编程(ReentrantLock)

时间:2024-04-23 16:44:35浏览次数:26  
标签:编程 获取 lock ReentrantLock Sync 并发 线程 公平 final

ReentrantLock 是独占锁,每次只能有一个线程能获取到锁(支持重入)。其他未获取锁的线程会放入的CLH队列中,等待当前线程唤醒;

主要分为公平锁和非公平锁,由内部类FairSyncNoFairSync来实现。主要的区别在于非公平锁每次都会尝试竞争,竞争不到锁才会放入到CLH队列中

  • NonfairSync类

NonfairSync类继承了Sync类,表示采用非公平策略获取锁,其实现了Sync类中抽象的lock方法,源码如下:

// 非公平锁
static final class NonfairSync extends Sync {
    // 版本号
    private static final long serialVersionUID = 7316153563782823691L;

    // 获得锁
    final void lock() {
        if (compareAndSetState(0, 1)) // 比较并设置状态成功,状态0表示锁没有被占用
            // 把当前线程设置独占了锁
            setExclusiveOwnerThread(Thread.currentThread());
        else // 锁已经被占用,或者set失败
            // 以独占模式获取对象,忽略中断
            acquire(1); 
    }

    protected final boolean tryAcquire(int acquires) {
        return nonfairTryAcquire(acquires);
    }
}

说明: 从lock方法的源码可知,每一次都尝试获取锁,而并不会按照公平等待的原则进行等待,让等待时间最久的线程获得锁。

  • FairSync类

FairSync类也继承了Sync类,表示采用公平策略获取锁,其实现了Sync类中的抽象lock方法,源码如下:

// 公平锁
static final class FairSync extends Sync {
    // 版本序列化
    private static final long serialVersionUID = -3000897897090466540L;

    final void lock() {
        // 以独占模式获取对象,忽略中断
        acquire(1);
    }

    /**
        * Fair version of tryAcquire.  Don't grant access unless
        * recursive call or no waiters or is first.
        */
    // 尝试公平获取锁
    protected final boolean tryAcquire(int acquires) {
        // 获取当前线程
        final Thread current = Thread.currentThread();
        // 获取状态
        int c = getState();
        if (c == 0) { // 状态为0
            if (!hasQueuedPredecessors() &&
                compareAndSetState(0, acquires)) { // 不存在已经等待更久的线程并且比较并且设置状态成功
                // 设置当前线程独占
                setExclusiveOwnerThread(current);
                return true;
            }
        }
        else if (current == getExclusiveOwnerThread()) { // 状态不为0,即资源已经被线程占据
            // 下一个状态
            int nextc = c + acquires;
            if (nextc < 0) // 超过了int的表示范围
                throw new Error("Maximum lock count exceeded");
            // 设置状态
            setState(nextc);
            return true;
        }
        return false;
    }
}

说明: 跟踪lock方法的源码可知

主要区别就在于hasQueuedPredecessors方法,先会判断是否存在等待队列。

示例:

private ReentrantLock lock = new ReentrantLock();
public void test(){
    lock.lock();
	try {
        ...
    }finally {
       lock.unlock();
    }   
        
}

标签:编程,获取,lock,ReentrantLock,Sync,并发,线程,公平,final
From: https://www.cnblogs.com/luojw/p/18153196

相关文章

  • 软件开发与创新实践——结对编程
    实验目的本次学习的任务是通过两人结对编程(一个人Coding,一个人审核)的方式,来体会团队合作的过程。本次实验由我和2230232共同完成。编程题目小学老师要每周给同学出300道四则运算练习题。–这个程序有很多种实现方式:C/C++C#/VB.net/JavaExcelUnixShellEmacs/Powershell/......
  • 软件开发与创新——结对编程
    本次结对编程作业由我和学号2252406的同学一起编写一、题目:小学老师要求出300道四则运算练习题要求:两个运算符,都是100以内的数字,答案在0-1000之间。拓展功能:有除法时计算的结果保留两位小数,避免除0错误,回答错误的题目存到“错题本.txt”文件中,方便后续查看及改正。300道题全部......
  • day20-并发编程(下)
    1.多进程开发进程是计算机中资源分配的最小单元;一个进程中可以有多个线程,同一个进程中的线程共享资源;进程与进程之间则是相互隔离。Python中通过多进程可以利用CPU的多核优势,计算密集型操作适用于多进程。1.1进程介绍importmultiprocessingdeftask(): passif__name......
  • 异步编程模型
    本文内容异步编程提升响应能力异步方法易于编写异步方法的运行机制API异步方法显示另外6个通过使用异步编程,你可以避免性能瓶颈并增强应用程序的总体响应能力。但是,编写异步应用程序的传统技术可能比较复杂,使它们难以编写、调试和维护。C#支持简化的方法,即异步编程,它......
  • 【微电平台】-高并发实战经验-奇葩问题解决及流程优化之旅
    微电平台微电平台是集电销、企业微信等于一体的综合智能SCRMSAAS化系统,涵盖多渠道管理、全客户生命周期管理、私域营销运营等主要功能,承接了京东各业务线服务,专注于为业务提供职场外包式的一站式客户管理及一体化私域运营服务。 导读本文介绍电销系统【客户名单离线打标......
  • 认识一下JavaScrip中的元编程
    本文分享自华为云社区《元编程,使代码更具描述性、表达性和灵活性》,作者:叶一一。背景去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。没有计划的阅读,收效甚微。新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一......
  • Windows编程系列:设置资源管理器背景
    偶然的机会,在github上发现了一个有趣且优秀的项目,https://github.com/Maplespe/explorerTool。这里学习了一下,并顺带学习了一下涉及的相关知识点。不得不感叹作者的厉害之处,能想到这种方法。 主要实现原理是:1、通过ApiHook,在调用CreateWindows函数创建窗口时,如果是资源管理器......
  • 实验3_C语言函数应用编程
    Task11#include<stdio.h>2#include<stdlib.h>3#include<time.h>4#include<windows.h>5#defineN8067voidprint_text(intline,intcol,chartext[]);8voidprint_spaces(intn);9voidprint_blank_lines(intn)......
  • Python企业面试题5 —— 网络编程和并发
    1.简述进程、线程和协程的区别以及应用场景?#进程:拥有自己独立的堆和栈,既不共享堆,也不共享栈,进程由操作系统调度。#线程:拥有自己独立的栈和共享的堆,线程也由操作系统调度。#协程和线程:协程避免了无意义的调度,由此可以提高性能;但同时协程失去了线程使用多CPU的能力。进程与......
  • linux系统是未来_大小写敏感_case_sensitive_编程原生态
    修改py文件......