公平锁和非公平锁,为什么要“非公平”?

公平锁和非公平锁,为什么要“非公平”?

主要讲一讲公平锁和非公平锁,以及为什么要“非公平”?

什么是公平和非公平

首先,我们来看下什么是公平锁和非公平锁,公平锁指的是按照线程请求的顺序,来分配锁;而非公平锁指的是不完全按照请求的顺序,在一定情况下,可以允许插队。但需要注意这里的非公平并不是指完全的随机,不是说线程可以任意插队,而是仅仅“在合适的时机”插队。

那么什么时候是合适的时机呢?假设当前线程在请求获取锁的时候,恰巧前一个持有锁的线程释放了这把锁,那么当前申请锁的线程就可以不顾已经等待的线程而选择立刻插队。但是如果当前线程请求的时候,前一个线程并没有在那一时刻释放锁,那么当前线程还是一样会进入等待队列。

为了能够更好的理解公平锁和非公平锁,我们举一个生活中的例子,假设我们还在学校读书,去食堂排队买饭,我排在队列的第二个,我前面还有一位同学,但此时我脑子里想的不是午饭,而是上午的一道数学题并陷入深思,所以当前面的同学打完饭之后轮到我时我走神了,并也没注意到现在轮到我了,此时前面的同学突然又回来插队,说“不好意思,阿姨麻烦给我加个鸡腿”,像这样的行为就可以类比我们的公平锁和非公平锁。

看到这里,你可能不解,为什么要设置非公平策略呢,而且非公平还是 ReentrantLock的默认策略,如果我们不加以设置的话默认就是非公平的,难道我的这些排队的时间都白白浪费了吗,为什么别人比我有优先权呢?毕竟公平是一种很好的行为,而非公平是一种不好的行为。

让我们考虑一种情况,假设线程 A 持有一把锁,线程 B 请求这把锁,由于线程 A 已经持有这把锁了,所以线程 B 会陷入等待,在等待的时候线程 B 会被挂起,也就是进入阻塞状态,那么当线程 A 释放锁的时候,本该轮到线程 B 苏醒获取锁,但如果此时突然有一个线程 C 插队请求这把锁,那么根据非公平的策略,会把这把锁给线程 C,这是因为唤醒线程 B 是需要很大开销的,很有可能在唤醒之前,线程 C 已经拿到了这把锁并且执行完任务释放了这把锁。相比于等待唤醒线程 B 的漫长过程,插队的行为会让线程 C 本身跳过陷入阻塞的过程,如果在锁代码中执行的内容不多的话,线程 C 就可以很快完成任务,并且在线程 B 被完全唤醒之前,就把这个锁交出去,这样是一个双赢的局面,对于线程 C 而言,不需要等待提高了它的效率,而对于线程 B 而言,它获得锁的时间并没有推迟,因为等它被唤醒的时候,线程 C 早就释放锁了,因为线程 C 的执行速度相比于线程 B 的唤醒速度,是很快的,所以 Java 设计者设计非公平锁,是为了提高整体的运行效率。

公平的场景

下面我们用图示来说明公平和非公平的场景,先来看公平的情况。假设我们创建了一个公平锁,此时有 4 个线程按顺序来请求公平锁,线程 1 在拿到这把锁之后,线程 2、3、4 会在等待队列中开始等待,然后等线程 1 释放锁之后,线程 2、3、4 会依次去获取这把锁,线程 2 先获取到的原因是它等待的时间最长。

不公平的场景

下面我们再来看看非公平的情况,假设线程 1 在解锁的时候,突然有线程 5 尝试获取这把锁,那么根据我们的非公平策略,线程 5 是可以拿到这把锁的,尽管它没有进入等待队列,而且线程 2、3、4 等待的时间都比线程 5 要长,但是从整体效率考虑,这把锁此时还是会交给线程 5 持有。

代码案例:演示公平和非公平的效果

下面我们来用代码演示看下公平和非公平的实际效果,代码如下:

我们可以通过改变 new ReentrantLock(false) 中的参数来设置公平/非公平锁。以上代码在公平的情况下的输出:

2024-03-25 22:40:18.729 [Thread 0] INFO org.dingchuan.FairAndUnfair - Thread 0: Going to print a job

2024-03-25 22:40:18.734 [Thread 0] INFO org.dingchuan.FairAndUnfair - Thread 0: PrintQueue: Printing a Job during 9 seconds

2024-03-25 22:40:18.829 [Thread 1] INFO org.dingchuan.FairAndUnfair - Thread 1: Going to print a job

2024-03-25 22:40:18.934 [Thread 2] INFO org.dingchuan.FairAndUnfair - Thread 2: Going to print a job

2024-03-25 22:40:19.038 [Thread 3] INFO org.dingchuan.FairAndUnfair - Thread 3: Going to print a job

2024-03-25 22:40:19.143 [Thread 4] INFO org.dingchuan.FairAndUnfair - Thread 4: Going to print a job

2024-03-25 22:40:19.248 [Thread 5] INFO org.dingchuan.FairAndUnfair - Thread 5: Going to print a job

2024-03-25 22:40:19.353 [Thread 6] INFO org.dingchuan.FairAndUnfair - Thread 6: Going to print a job

2024-03-25 22:40:19.459 [Thread 7] INFO org.dingchuan.FairAndUnfair - Thread 7: Going to print a job

2024-03-25 22:40:19.564 [Thread 8] INFO org.dingchuan.FairAndUnfair - Thread 8: Going to print a job

2024-03-25 22:40:19.668 [Thread 9] INFO org.dingchuan.FairAndUnfair - Thread 9: Going to print a job

2024-03-25 22:40:28.515 [Thread 0] INFO org.dingchuan.FairAndUnfair - Thread 0: PrintQueue: Printing a Job during 1 seconds

2024-03-25 22:40:30.031 [Thread 0] INFO org.dingchuan.FairAndUnfair - Thread 0: The document has been printed

2024-03-25 22:40:30.031 [Thread 1] INFO org.dingchuan.FairAndUnfair - Thread 1: PrintQueue: Printing a Job during 4 seconds

2024-03-25 22:40:34.983 [Thread 1] INFO org.dingchuan.FairAndUnfair - Thread 1: PrintQueue: Printing a Job during 1 seconds

2024-03-25 22:40:36.441 [Thread 1] INFO org.dingchuan.FairAndUnfair - Thread 1: The document has been printed

2024-03-25 22:40:36.441 [Thread 2] INFO org.dingchuan.FairAndUnfair - Thread 2: PrintQueue: Printing a Job during 6 seconds

2024-03-25 22:40:42.711 [Thread 2] INFO org.dingchuan.FairAndUnfair - Thread 2: PrintQueue: Printing a Job during 6 seconds

2024-03-25 22:40:49.046 [Thread 3] INFO org.dingchuan.FairAndUnfair - Thread 3: PrintQueue: Printing a Job during 0 seconds

2024-03-25 22:40:49.046 [Thread 2] INFO org.dingchuan.FairAndUnfair - Thread 2: The document has been printed

2024-03-25 22:40:49.564 [Thread 3] INFO org.dingchuan.FairAndUnfair - Thread 3: PrintQueue: Printing a Job during 1 seconds

2024-03-25 22:40:50.764 [Thread 3] INFO org.dingchuan.FairAndUnfair - Thread 3: The document has been printed

2024-03-25 22:40:50.764 [Thread 4] INFO org.dingchuan.FairAndUnfair - Thread 4: PrintQueue: Printing a Job during 4 seconds

2024-03-25 22:40:55.324 [Thread 4] INFO org.dingchuan.FairAndUnfair - Thread 4: PrintQueue: Printing a Job during 8 seconds

2024-03-25 22:41:03.510 [Thread 5] INFO org.dingchuan.FairAndUnfair - Thread 5: PrintQueue: Printing a Job during 8 seconds

2024-03-25 22:41:03.510 [Thread 4] INFO org.dingchuan.FairAndUnfair - Thread 4: The document has been printed

2024-03-25 22:41:11.570 [Thread 5] INFO org.dingchuan.FairAndUnfair - Thread 5: PrintQueue: Printing a Job during 5 seconds

2024-03-25 22:41:16.909 [Thread 5] INFO org.dingchuan.FairAndUnfair - Thread 5: The document has been printed

2024-03-25 22:41:16.909 [Thread 6] INFO org.dingchuan.FairAndUnfair - Thread 6: PrintQueue: Printing a Job during 0 seconds

2024-03-25 22:41:17.249 [Thread 6] INFO org.dingchuan.FairAndUnfair - Thread 6: PrintQueue: Printing a Job during 1 seconds

2024-03-25 22:41:18.997 [Thread 6] INFO org.dingchuan.FairAndUnfair - Thread 6: The document has been printed

2024-03-25 22:41:18.997 [Thread 7] INFO org.dingchuan.FairAndUnfair - Thread 7: PrintQueue: Printing a Job during 3 seconds

2024-03-25 22:41:22.274 [Thread 7] INFO org.dingchuan.FairAndUnfair - Thread 7: PrintQueue: Printing a Job during 8 seconds

2024-03-25 22:41:30.919 [Thread 8] INFO org.dingchuan.FairAndUnfair - Thread 8: PrintQueue: Printing a Job during 3 seconds

2024-03-25 22:41:30.919 [Thread 7] INFO org.dingchuan.FairAndUnfair - Thread 7: The document has been printed

2024-03-25 22:41:34.277 [Thread 8] INFO org.dingchuan.FairAndUnfair - Thread 8: PrintQueue: Printing a Job during 8 seconds

2024-03-25 22:41:42.283 [Thread 8] INFO org.dingchuan.FairAndUnfair - Thread 8: The document has been printed

2024-03-25 22:41:42.283 [Thread 9] INFO org.dingchuan.FairAndUnfair - Thread 9: PrintQueue: Printing a Job during 5 seconds

2024-03-25 22:41:47.828 [Thread 9] INFO org.dingchuan.FairAndUnfair - Thread 9: PrintQueue: Printing a Job during 2 seconds

2024-03-25 22:41:50.104 [Thread 9] INFO org.dingchuan.FairAndUnfair - Thread 9: The document has been printed

可以看出,线程直接获取锁的顺序是完全公平的,先到先得。

而以上代码在非公平的情况下的输出是这样的:

2024-03-25 22:50:51.131 [Thread 0] INFO org.dingchuan.FairAndUnfair - Thread 0: Going to print a job

2024-03-25 22:50:51.135 [Thread 0] INFO org.dingchuan.FairAndUnfair - Thread 0: PrintQueue: Printing a Job during 7 seconds

2024-03-25 22:50:51.231 [Thread 1] INFO org.dingchuan.FairAndUnfair - Thread 1: Going to print a job

2024-03-25 22:50:51.335 [Thread 2] INFO org.dingchuan.FairAndUnfair - Thread 2: Going to print a job

2024-03-25 22:50:51.440 [Thread 3] INFO org.dingchuan.FairAndUnfair - Thread 3: Going to print a job

2024-03-25 22:50:51.545 [Thread 4] INFO org.dingchuan.FairAndUnfair - Thread 4: Going to print a job

2024-03-25 22:50:51.650 [Thread 5] INFO org.dingchuan.FairAndUnfair - Thread 5: Going to print a job

2024-03-25 22:50:51.751 [Thread 6] INFO org.dingchuan.FairAndUnfair - Thread 6: Going to print a job

2024-03-25 22:50:51.855 [Thread 7] INFO org.dingchuan.FairAndUnfair - Thread 7: Going to print a job

2024-03-25 22:50:51.956 [Thread 8] INFO org.dingchuan.FairAndUnfair - Thread 8: Going to print a job

2024-03-25 22:50:52.061 [Thread 9] INFO org.dingchuan.FairAndUnfair - Thread 9: Going to print a job

2024-03-25 22:50:58.649 [Thread 1] INFO org.dingchuan.FairAndUnfair - Thread 1: PrintQueue: Printing a Job during 0 seconds

2024-03-25 22:50:59.317 [Thread 2] INFO org.dingchuan.FairAndUnfair - Thread 2: PrintQueue: Printing a Job during 3 seconds

2024-03-25 22:51:02.323 [Thread 3] INFO org.dingchuan.FairAndUnfair - Thread 3: PrintQueue: Printing a Job during 7 seconds

2024-03-25 22:51:10.014 [Thread 4] INFO org.dingchuan.FairAndUnfair - Thread 4: PrintQueue: Printing a Job during 2 seconds

2024-03-25 22:51:12.580 [Thread 5] INFO org.dingchuan.FairAndUnfair - Thread 5: PrintQueue: Printing a Job during 2 seconds

2024-03-25 22:51:14.820 [Thread 6] INFO org.dingchuan.FairAndUnfair - Thread 6: PrintQueue: Printing a Job during 5 seconds

2024-03-25 22:51:19.838 [Thread 7] INFO org.dingchuan.FairAndUnfair - Thread 7: PrintQueue: Printing a Job during 1 seconds

2024-03-25 22:51:20.861 [Thread 8] INFO org.dingchuan.FairAndUnfair - Thread 8: PrintQueue: Printing a Job during 0 seconds

2024-03-25 22:51:20.991 [Thread 9] INFO org.dingchuan.FairAndUnfair - Thread 9: PrintQueue: Printing a Job during 5 seconds

2024-03-25 22:51:26.370 [Thread 0] INFO org.dingchuan.FairAndUnfair - Thread 0: PrintQueue: Printing a Job during 1 seconds

2024-03-25 22:51:28.195 [Thread 0] INFO org.dingchuan.FairAndUnfair - Thread 0: The document has been printed

2024-03-25 22:51:28.195 [Thread 1] INFO org.dingchuan.FairAndUnfair - Thread 1: PrintQueue: Printing a Job during 6 seconds

2024-03-25 22:51:34.404 [Thread 2] INFO org.dingchuan.FairAndUnfair - Thread 2: PrintQueue: Printing a Job during 1 seconds

2024-03-25 22:51:34.404 [Thread 1] INFO org.dingchuan.FairAndUnfair - Thread 1: The document has been printed

2024-03-25 22:51:36.131 [Thread 2] INFO org.dingchuan.FairAndUnfair - Thread 2: The document has been printed

2024-03-25 22:51:36.131 [Thread 3] INFO org.dingchuan.FairAndUnfair - Thread 3: PrintQueue: Printing a Job during 3 seconds

2024-03-25 22:51:39.303 [Thread 4] INFO org.dingchuan.FairAndUnfair - Thread 4: PrintQueue: Printing a Job during 0 seconds

2024-03-25 22:51:39.303 [Thread 3] INFO org.dingchuan.FairAndUnfair - Thread 3: The document has been printed

2024-03-25 22:51:39.485 [Thread 4] INFO org.dingchuan.FairAndUnfair - Thread 4: The document has been printed

2024-03-25 22:51:39.485 [Thread 5] INFO org.dingchuan.FairAndUnfair - Thread 5: PrintQueue: Printing a Job during 4 seconds

2024-03-25 22:51:43.563 [Thread 5] INFO org.dingchuan.FairAndUnfair - Thread 5: The document has been printed

2024-03-25 22:51:43.563 [Thread 6] INFO org.dingchuan.FairAndUnfair - Thread 6: PrintQueue: Printing a Job during 0 seconds

2024-03-25 22:51:44.197 [Thread 6] INFO org.dingchuan.FairAndUnfair - Thread 6: The document has been printed

2024-03-25 22:51:44.197 [Thread 7] INFO org.dingchuan.FairAndUnfair - Thread 7: PrintQueue: Printing a Job during 0 seconds

2024-03-25 22:51:44.281 [Thread 7] INFO org.dingchuan.FairAndUnfair - Thread 7: The document has been printed

2024-03-25 22:51:44.282 [Thread 8] INFO org.dingchuan.FairAndUnfair - Thread 8: PrintQueue: Printing a Job during 9 seconds

2024-03-25 22:51:53.927 [Thread 8] INFO org.dingchuan.FairAndUnfair - Thread 8: The document has been printed

2024-03-25 22:51:53.927 [Thread 9] INFO org.dingchuan.FairAndUnfair - Thread 9: PrintQueue: Printing a Job during 6 seconds

2024-03-25 22:52:00.884 [Thread 9] INFO org.dingchuan.FairAndUnfair - Thread 9: The document has been printed

可以看出,非公平情况下,存在抢锁“插队”的现象,比如Thread 0 在释放锁后又能优先获取到锁,虽然此时在等待队列中已经有 Thread 1 ~ Thread 9 在排队了。

对比公平和非公平的优缺点

我们接下来对比公平和非公平的优缺点,如表格所示。

公平锁的优点在于各个线程公平平等,每个线程等待一段时间后,都有执行的机会,而它的缺点就在于整体执行速度更慢,吞吐量更小,相反非公平锁的优势就在于整体执行速度更快,吞吐量更大,但同时也可能产生线程饥饿问题,也就是说如果一直有线程插队,那么在等待队列中的线程可能长时间得不到运行。

源码分析

下面我们来分析公平和非公平锁的源码,具体看下它们是怎样实现的,可以看到在 ReentrantLock 类包含一个 Sync 类,这个类继承自AQS(AbstractQueuedSynchronizer),代码如下:

public class ReentrantLock implements Lock, java.io.Serializable {
	private static final long serialVersionUID = 7373984872572414699L;
	/** Synchronizer providing all implementation mechanics */
	private final Sync sync;

Sync 类的代码:

abstract static class Sync extends AbstractQueuedSynchronizer {...}

根据代码可知,Sync 有公平锁 FairSync 和非公平锁 NonfairSync两个子类:

static final class NonfairSync extends Sync {...}
static final class FairSync extends Sync {...}

下面我们来看一下公平锁与非公平锁的加锁方法的源码。

公平锁的锁获取源码如下:

protected final boolean tryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    int c = getState();
    if (c == 0) {
        if (!hasQueuedPredecessors() && //这里判断了 hasQueuedPredecessors()
               compareAndSetState(0, acquires)) {
            setExclusiveOwnerThread(current);
            return true;
        }

    } else if (current == getExclusiveOwnerThread()) {
        int nextc = c + acquires;
        if (nextc < 0) {
            throw new Error("Maximum lock count exceeded");
        }
        setState(nextc);
        return true;
    }
    return false;
}

非公平锁的锁获取源码如下:

final boolean nonfairTryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    int c = getState();
    if (c == 0) {
        if (compareAndSetState(0, acquires)) { //这里没有判断      hasQueuedPredecessors()
            setExclusiveOwnerThread(current);
            return true;
        }
    }

    else if (current == getExclusiveOwnerThread()) {
        int nextc = c + acquires;
        if (nextc < 0) // overflow
          throw new Error("Maximum lock count exceeded");
        setState(nextc);
        return true;
    }
    return false;
}

通过对比,我们可以明显的看出公平锁与非公平锁的 lock() 方法唯一的区别就在于公平锁在获取锁时多了一个限制条件:hasQueuedPredecessors() 为 false,这个方法就是判断在等待队列中是否已经有线程在排队了。这也就是公平锁和非公平锁的核心区别,如果是公平锁,那么一旦已经有线程在排队了,当前线程就不再尝试获取锁;对于非公平锁而言,无论是否已经有线程在排队,都会尝试获取一下锁,获取不到的话,再去排队。

这里有一个特例需要我们注意,针对 tryLock() 方法,它不遵守设定的公平原则。

例如,当有线程执行 tryLock() 方法的时候,一旦有线程释放了锁,那么这个正在 tryLock 的线程就能获取到锁,即使设置的是公平锁模式,即使在它之前已经有其他正在等待队列中等待的线程,简单地说就是 tryLock 可以插队。

看它的源码就会发现:

public boolean tryLock() {
    return sync.nonfairTryAcquire(1);
}

这里调用的就是 nonfairTryAcquire(),表明了是不公平的,和锁本身是否是公平锁无关。

综上所述,公平锁就是会按照多个线程申请锁的顺序来获取锁,从而实现公平的特性。非公平锁加锁时不考虑排队等待情况,直接尝试获取锁,所以存在后申请却先获得锁的情况,但由此也提高了整体的效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/487549.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

欧科云链OKLink:坎昆升级后,Layer2项目是否更具竞争力?

在坎昆升级激活之际&#xff0c;OKLink 上线以太坊坎昆升级 Dencun 专题页 &#x1f449; 从专业链上数据分析角度&#xff0c;带来一场充实且即时的 Layer2 数据盛宴。 在近日由 137Labs 发起&#xff0c;Cointime 主持的 Layer2 生态专场讨论中&#xff0c;OKLink 产品…

AISD智能安全配电装置--智能监测、远程监控

安科瑞薛瑶瑶18701709087 AISD100单相、AISD300三相智能安全配电装置是安科瑞专为低压配电侧开发的一款智能安全配电产品。主要针对低压配电系统人身触电、线路老化、短路、漏电等原因引起电气安全问题而设计。 产品主要应用于学校、加油站、医院、银行、疗养院、康复中心、敬…

补充--广义表学习

第一章 逻辑结构 &#xff08;1&#xff09;A()&#xff0c;A是一个空表&#xff0c;长度为0&#xff0c;深度为1。 &#xff08;2&#xff09;B(d,e)&#xff0c;B的元素全是原子&#xff0c;d和e&#xff0c;长度为2&#xff0c;深度为1。 &#xff08;3&#xff09;C(b,(c,…

什么事缓存击穿、缓存穿透、缓存雪崩?

缓存击穿&#xff1a;是指当某一个key的缓存过期时大并发量的请求同时访问此key&#xff0c;瞬间击穿缓存服务器直接访问数据库&#xff0c;让数据库处于负载的情况。 缓存穿透&#xff1a;是指缓存服务器中没有缓存数据&#xff0c;数据库中也没有符合条件的数据&#xff0c;…

2024 ccfcsp认证打卡 2023 09 02 坐标变换(其二)

202309-2 坐标变换&#xff08;其二&#xff09; 题解1题解2区别第一种算法&#xff08;使用ArrayList存储操作序列&#xff09;&#xff1a;数据结构&#xff1a;操作序列处理&#xff1a; 第二种算法&#xff08;使用两个数组存储累积结果&#xff09;&#xff1a;数据结构&a…

微服务day06 -- Elasticsearch的数据搜索功能。分别使用DSL和RestClient实现搜索

1.DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 1.1.DSL查询分类 Elasticsearch提供了基于JSON的DSL&#xff08;Domain Specific Language&#xff09;来定义查询。常见的查询类型包括&#xff1a; 查询所有&#xff1a;查询出所有数据&#xff0c;一…

代码随想录算法训练营day57|647. 回文子串 、 516.最长回文子序列

目录 647. 回文子串 16.最长回文子序列 647. 回文子串 力扣题目链接(opens new window) 给定一个字符串&#xff0c;你的任务是计算这个字符串中有多少个回文子串。 具有不同开始位置或结束位置的子串&#xff0c;即使是由相同的字符组成&#xff0c;也会被视作不同的子串…

每天学点儿python(1)---print,input和注释

print函数 print语法格式 print(*objects, sep , end\n, filesys.stdout) sep参数默认为 一个空格 end&#xff08;输出末尾&#xff09;参数默认为 回车换行 file默认为 标准输出&#xff08;一般指屏幕&#xff09; 所以&#xff0c;如果想输出各个字段不用空格隔开&a…

人工智能三剑客NumPy、pandas、matplotlib和Jupyter四者之间的关系

NumPy 主要用途&#xff1a;NumPy&#xff08;Numerical Python的缩写&#xff09;主要用于处理大型多维数组和矩阵的科学计算。它提供了一个高性能的多维数组对象&#xff0c;以及用于数组操作的工具。与其他三者的联系&#xff1a;NumPy是pandas和matplotlib的基础库之一。许…

前端基础 Vue -组件化基础

1.全局组件 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><script src&…

如何搭建ERP帮助中心提升工作效率

现在是个信息化时代&#xff0c;ERP系统成了企业日常运营里必不可少的一部分。不过&#xff0c;随着ERP系统用得越来越多&#xff0c;大家在使用过程中碰到的问题变得多且复杂。为了解决这些麻烦&#xff0c;提高大家的工作效率&#xff0c;搭建ERP帮助中心其实是一个很有必要的…

FreeRTOS从代码层面进行原理分析(2 任务的启动)

FreeRTOS分析二—任务的启动 上一篇文章我们带着三个问题开始了对 FreeRTOS 代码的探究。 1. FreeRTOS 是如何建立任务的呢&#xff1f; 2. FreeRTOS 是调度和切换任务的呢&#xff1f; 3. FreeRTOS 是如何保证实时性呢&#xff1f; 并且在上一篇文章 FreeRTOS从代码层面进行…

学习刷题-13

3.23 hw机试【二叉树】 剑指offer32 剑指 offer32&#xff08;一、二、三&#xff09;_剑指offer 32-CSDN博客 从上到下打印二叉树I 一棵圣诞树记作根节点为 root 的二叉树&#xff0c;节点值为该位置装饰彩灯的颜色编号。请按照从 左 到 右 的顺序返回每一层彩灯编号。 输…

产品推荐 | 基于 Zynq UltraScale+ XCZU27DR的 FACE-RFSoC-C高性能自适应射频开发平台

一、产品概述 FACE-RFSOC-C自适应射频开发平台&#xff0c;是FACE系列新一代的产品。 平台搭载有16nm工艺的Zynq UltraScale™ RFSoC系列主器件。该器件集成数千兆采样RF数据转换器和ARM Cortex-A53处理子系统和UltraScale可编程逻辑&#xff0c;是一款单芯片自适应射频平台。…

电脑卸载软件怎么清理干净?电脑清理的5种方法

随着我们在电脑上安装和卸载各种软件&#xff0c;很多时候我们会发现&#xff0c;即使软件被卸载&#xff0c;其残留的文件和注册表项仍然存在于电脑中&#xff0c;这不仅占用了宝贵的磁盘空间&#xff0c;还可能影响电脑的性能。那么&#xff0c;如何确保在卸载软件时能够彻底…

FakeLocation报虚拟位置服务连接失败,请重启设备再试

虚拟位置服务连接失败&#xff0c;请重启设备再试 最近遇到一个手机软件报的bug“虚拟位置服务连接失败&#xff0c;请重启设备再试” 因为我的实体“虚拟机”已经root&#xff0c;按道理是不可能报这个错的 折腾了2天&#xff0c;终于解决了 原来是这样&#xff0c;安装最新…

Linux文件系统 底层原理

linux文件、目录、Inode inode负责文件的元数据和数据存储&#xff0c;文件存储块负责实际数据的存储&#xff0c;而目录文件维护文件名和inode之间的联系。 1. 用户空间到内核空间 首先&#xff0c;当用户程序请求打开一个文件时&#xff08;例如使用open系统调用&#xff09…

关系型数据库mysql(6)备份与恢复

一.数据备份的重要性 &#xff08;1&#xff09;在生产环境中&#xff0c;数据的安全性至关重要 &#xff08;2&#xff09;任何数据的丢失都可能产生严重的后果 &#xff08;3&#xff09;造成数据丢失的原因 程序错误人为操作失误运算错误磁盘故障灾难&#xff08;如火灾…

YOLOv9改进策略:卷积魔改 | SCConv:空间和通道重建卷积,即插即用,助力检测 | CVPR2023

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文改进内容&#xff1a; CVPR2023 SCConv 由两个单元组成&#xff1a;空间重建单元&#xff08;SRU&#xff09;和通道重建单元&#xff08;CRU&#xff09;。 SRU利用分离重建方法来抑制空间冗余&#xff0c;而CRU使用分割-变换-融…

ssm004新生报到系统+jsp

新生报到系统的设计与实现 摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对新生报到信息管理混乱&#xff0c;出错率…