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

news2024/11/26 16:57:51

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

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

什么是公平和非公平

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

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

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

看到这里,你可能不解,为什么要设置非公平策略呢,而且非公平还是 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(),表明了是不公平的,和锁本身是否是公平锁无关。

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

对话式 AI 的天花板来了,Hume AI 再拿 5000 万美金融资

Hume AI 刚刚推出了世界上第一款共情 AI 语音接口 EVI&#xff0c;它可以让开发人员能够通过几行代码将情感智能人工智能语音集成到健康和保健、AR/VR、客户服务呼叫中心、医疗保健等领域的应用程序中。 之前我介绍过好几个对话式 AI 产品&#xff0c;或者也可以将它们称为 AI…

WebPack的使用及属性配、打包资源

WebPack(静态模块打包工具)(webpack默认只识别js和json内容) WebPack的作用 把静态模块内容压缩、整合、转译等&#xff08;前端工程化&#xff09; 1️⃣把less/sass转成css代码 2️⃣把ES6降级成ES5 3️⃣支持多种模块文件类型&#xff0c;多种模块标准语法 export、export…

STM32之HAL开发——串口配置(CubeMX)

串口引脚初始化&#xff08;CubeMX&#xff09; 选择RCC时钟来源 选择时钟频率&#xff0c;配置为最高频率72MHZ 将单片机调试模式打开 SW模式 选择窗口一配置为异步通信模式 点击IO口设置页面&#xff0c;可以看到当前使用的串口一的引脚。如果想使用复用功能&#xff0c;只需…

状态压缩dp[详解 + 例题]

1 . 题目 2 . 分析 可以发现 : 横放的方案数 总方案数 ; 剩下的都是竖放去填补空缺 ; 关于状态定义 : 考虑按列拜访 &#xff0c; 某列的隔行用0/1表示摆放状态 ; 某行为1 : 表示横放 , 0 : 表示竖放 ; 状态表示 : f[i][j] : 表示拜访第i列&#xff0c;状态为j的方案数…

6_springboot_shiro_jwt_多端认证鉴权_过滤器链

1. Shiro过滤器链 ​ Shiro中可以配置多个Filter&#xff0c;那么Shiro是如何管理这些过滤器的&#xff1f;主要是靠ShiroFilterFactoryBean 它是一个Spring Bean&#xff0c;用于在Spring应用中配置Shiro的Web过滤器链。过滤器链是一系列按照特定顺序排列的过滤器&#xff0c…

关于Devc++调试的问题以及解决STL变量无法查看

目前Devc的调试主要有以下几点&#xff1a; 1.调试不能直接查看stl变量&#xff0c;会卡死不动 2.目前单步进入只能用鼠标键按 3.若想按下一步进入函数体内&#xff0c;要在函数体内打上断点才行 4.调试到return 0 ;上一句就停了&#xff0c;不会结束程序 5.目前F2跳至断点…

代码随想录训练营Day35:● 860.柠檬水找零 ● 406.根据身高重建队列 ● 452. 用最少数量的箭引爆气球

860.柠檬水找零 题目链接 https://leetcode.cn/problems/lemonade-change/description/ 题目描述 思路 class Solution {public boolean lemonadeChange(int[] bills) {int five 0,ten 0,twenty 0;for (int i 0; i < bills.length; i) {if(bills[i] 5){five;}else i…

记录在项目中引用本地的npm包

1、先把需要的包下载下来&#xff0c;以Photo Sphere Viewer 为引用的npm包、项目以shpereRepo为例子 git clone https://github.com/mistic100/Photo-Sphere-Viewer2、拉下代码后修改之后执行 ./build.sh build.sh #!/usr/bin/env bashyarn run build targetDir"../sh…

SpringBoot 登录认证(二)

HTTP是无状态协议 HTTP协议是无状态协议。什么又是无状态的协议&#xff1f; 所谓无状态&#xff0c;指的是每一次请求都是独立的&#xff0c;下一次请求并不会携带上一次请求的数据。而浏览器与服务器之间进行交互&#xff0c;基于HTTP协议也就意味着现在我们通过浏览器来访…

jmeter中参数加密

加密接口常用的方式有&#xff1a; MD5&#xff0c;SHA&#xff0c;HmacSHA RSA AES&#xff0c;DES&#xff0c;Base64 压测中有些参数需要进行加密&#xff0c;加密方式已接口文档为主。 MD5加密 比如MD5加密的接口文档&#xff1a; 请求URL&#xff1a;http://101.34.221…

Unity AI Navigation自动寻路

目录 前言一、Unity中AI Navigation是什么&#xff1f;二、使用步骤1.安装AI Navigation2.创建模型和材质3.编写向目标移动的脚本4.NavMeshLink桥接组件5.NavMeshObstacle组件6.NavMeshModifler组件 三、效果总结 前言 Unity是一款强大的游戏开发引擎&#xff0c;而人工智能&a…

基于单片机病房呼叫系统数码管显示房号设计

**单片机设计介绍&#xff0c;基于单片机病房呼叫系统数码管显示房号设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机病房呼叫系统数码管显示房号设计概要主要涵盖了利用单片机技术实现病房呼叫系统&#xff0c;并…

基于springboot实现校园周边美食探索及分享平台系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现园周边美食探索及分享平台系统演示 摘要 美食一直是与人们日常生活息息相关的产业。传统的电话订餐或者到店消费已经不能适应市场发展的需求。随着网络的迅速崛起&#xff0c;互联网日益成为提供信息的最佳俱渠道和逐步走向传统的流通领域&#xff0c;传统的…

【SpringCloud】Ribbon负载均衡

&#x1f3e1;浩泽学编程&#xff1a;个人主页 &#x1f525; 推荐专栏&#xff1a;《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》《项目实战》 &#x1f6f8;学无止境&#xff0c;不骄不躁&#xff0c;知行合一 文章目录 …

新家装修选中央空调如何选?认准约克VRF中央空调

在现代家居生活中,追求舒适和健康生活环境的家庭越来越倾向于选择中央空调系统。面对市场上琳琅满目的中央空调品牌,如何挑选一款合适的家用中央空调成为许多消费者的一大难题。今天,我们以约克VRF中央空调为例,深入探讨其特点和优势,为广大家庭提供一个舒适的选择答案。 首先…

玩美移动升级虚拟试妆体验: 推出3D多色腮红AR试妆解决方案

领先的AI和AR美妆和时尚技术解决方案供应商&#xff0c;以及“美力AI”解决方案开发商——玩美移动于今天宣布&#xff0c;其3D腮红虚拟试妆工具已实现进一步技术提升。用户可以通过三色腮红虚拟试妆体验&#xff0c;尝试更多腮红色号、质地以及多种颜色组合妆效。本次虚拟试妆…

应用方案 D431L可调精密基准源,可耐压35V以上

概述 D431L是一种低压三端可调稳压器&#xff0c;保证在适用温度范围内的热稳定性。输出电压可以设置为VREF(约1.24V)~16V&#xff08;接两个外部电阻&#xff09;。该装置具有典型的动态输出0.2Ω的阻抗。在很多应用中&#xff0c;可替代齐纳二极管。 D431L有TO-92和SOT23封装…

Go打造REST Server【二】:用路由的三方库来实现

前言 在之前的文章中&#xff0c;我们用Go的标准库来实现了服务器&#xff0c;JSON渲染重构为辅助函数&#xff0c;使特定的路由处理程序相当简洁。 我们剩下的问题是路径路由逻辑&#xff0c;这是所有编写无依赖HTTP服务器的人都会遇到的问题&#xff0c;除非服务器只处理一到…

用xshell或ftp连接本地虚拟机linux系统,centos7修改动态ip地址

如果不知道怎么下载vm本地虚拟机软件或者不知道怎么安装可以参考我上一篇博客 vmWare虚拟机下载安装详细教程,手把手一步一步教学-CSDN博客 安装好虚拟机软件我们想要通过xshell和ftp工具来管理,小黑框不太舒服哈哈哈 一.准备工作 输入命令来查看当前的ip地址 ip addr 可以…

unity学习(76)--窗口化和后台运行

1.通过如下方式将编译的游戏设置为窗口模式。 成功&#xff1a; 2.现在只有鼠标点击的窗体游戏运动&#xff0c;其他窗体游戏都会卡住。 2.1build setting中 2.2unity内部Project Settings 也被同步修改了