java JUC并发编程 第十章 Synchronized与锁升级

news2024/11/27 19:42:48

系列文章目录

第一章 java JUC并发编程 Future: link
第二章 java JUC并发编程 多线程锁: link
第三章 java JUC并发编程 中断机制: link
第四章 java JUC并发编程 java内存模型JMM: link
第五章 java JUC并发编程 volatile与JMM: link
第六章 java JUC并发编程 CAS: link
第七章 java JUC并发编程 原子操作类增强: link
第八章 java JUC并发编程 ThreadLocal: link
第九章 java JUC并发编程 对象内存布局与对象头: link
第十章 java JUC并发编程 Synchronized与锁升级: link


文章目录

  • 系列文章目录
  • 1. 总纲
  • 2 Synchronized的性能变化
    • 2.1 java5之前,只有Synchronized,这个是操作系统级别的重量级操作
    • 2.2 为什么每一个对象都可以成为一个锁?
      • 2.2.1 markOOp.hpp
      • 2.2.2 Monitor(监视器锁)
      • 2.2.3 结合之前的synchronized和对象头说明
    • 2.3 java6开始,优化Synchronized
  • 3 synchronized锁种类及升级步骤
    • 3.1 多线程访问情况,3种
    • 3.2 升级流程
    • 3.3 无锁
      • 3.3.1 C源码的Mark Word标记
      • 3.3.2 Code演示(重点看注释或者自己运行)
      • 3.3.3 程序不会有锁的竞争
    • 3.4 偏锁
      • 3.4.1 单线程竞争
      • 3.4.2 细化案例Account对象举例说明
      • 3.4.3 偏向锁JVM命令
      • 3.4.4 无效果的code演示
      • 3.4.5 原因是因为参数系统默认开启
      • 3.4.6 关闭延时参数,启用该功能
      • 3.4.7 在idea的这里添加此参数
      • 3.4.8 开始有第二个线程竞争资源
      • 3.4.9 总体步骤流程图
    • 3.5 轻锁
      • 3.5.1 主要作用
      • 3.5.2 64位标记图
      • 3.5.3 轻量级锁的获取
      • 3.5.4 code
      • 3.5.5 步骤流程图
      • 3.5.6 自旋达到一定次数和程度
      • 3.5.7 轻量锁与偏向锁的区别和不同
    • 3.6 重锁
    • 3.7 总结
      • 3.7.1 锁升级发生后,hashcode去哪了?
  • 4 JIT编译器对锁的优化


1. 总纲

在这里插入图片描述
syncnronized锁:由对象头中的Mark Word根据锁标志位的不同而被复用及锁升级策略

2 Synchronized的性能变化

2.1 java5之前,只有Synchronized,这个是操作系统级别的重量级操作

重量级锁,假如锁的竞争比较激烈的话,性能下降
java5之前,用户态和内核之间的切换:
在这里插入图片描述

2.2 为什么每一个对象都可以成为一个锁?

2.2.1 markOOp.hpp

在这里插入图片描述

2.2.2 Monitor(监视器锁)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2.3 结合之前的synchronized和对象头说明

在这里插入图片描述
在这里插入图片描述

2.3 java6开始,优化Synchronized

java6之后,为了减少获得所和释放锁锁带来的性能消耗,引入了轻量级锁和偏向锁
需要有个逐步升级的过程,不能一开始就捅到重量级锁

3 synchronized锁种类及升级步骤

3.1 多线程访问情况,3种

1.只有一个线程来访问,有且唯一
2.有多个线程(2个线程A.B交替访问)
3.竞争激烈,更多个线程来访问

3.2 升级流程

synchronized用的锁是存在java对象头里的Mark Word中锁升级功能主要依赖Mark Work中锁标志位和释放偏向锁标志位
64位标记图:
在这里插入图片描述
偏向锁:MarkWord存储的是偏向的线程id
轻量锁:MarkWord存储的是指向线程栈中Lock Record的指针
重量锁:MarkWord存储的是指向堆中的monitor对象的指针

3.3 无锁

3.3.1 C源码的Mark Word标记

蓝色日志解读: 前25位没有用 31位存的hash 后面1位没有用 age:4(gc的留存) biased_lock(偏向状态)
在这里插入图片描述

3.3.2 Code演示(重点看注释或者自己运行)

package com.atguigu.springcloud.util.interrup;

import org.openjdk.jol.info.ClassLayout;

public class SynchronizedUpDemo {
    public static void main(String[] args) {
        /*Object o = new Object();
        System.out.println(ClassLayout.parseInstance(o).toPrintable());*/
        /**
         * 上面输出的结果:没有调用hashcode之前的输出
         *
         * java.lang.Object object internals:
         *  OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
         *       0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
         *       4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
         *       8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
         *      12     4        (loss due to the next object alignment)
         * Instance size: 16 bytes
         * Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
         *
         * 说明:14,15行就是64位的Mark word 只有第一位是1(从右下角到左上角倒着看)
         * hashcode:不是new一个对象就给你,而是有调用的时候才会生成
         */


        /*Object o = new Object();
        System.out.println("10进制:"+o.hashCode());//分调用和没调用打印的结果不一样
        System.out.println(ClassLayout.parseInstance(o).toPrintable());*/
        /**
         * o.hashCode代码加上后的打印结果
         *
         * 10进制:653305407
         * java.lang.Object object internals:
         *  OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
         *       0     4        (object header)                           01 3f a6 f0 (00000001 00111111 10100110 11110000) (-257540351)
         *       4     4        (object header)                           26 00 00 00 (00100110 00000000 00000000 00000000) (38)
         *       8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
         *      12     4        (loss due to the next object alignment)
         * Instance size: 16 bytes
         * Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
         *
         * 说明:发现hashCode位置已经有值了。
         */

        Object o = new Object();
        System.out.println("10进制:"+o.hashCode());
        System.out.println("16进制:"+Integer.toHexString(o.hashCode()));
        System.out.println("2进制:"+Integer.toBinaryString(o.hashCode()));
        System.out.println(ClassLayout.parseInstance(o).toPrintable());

        /**
         * 上面打印的输出情况:看55,56行对应的59,60行所对应的数字,依然是倒着看
         * 前25位没有用从31位是HashCode
         *
         * 10进制:653305407
         * 16进制:26f0a63f
         * 2进制:100110111100001010011000111111
         * java.lang.Object object internals:
         *  OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
         *       0     4        (object header)                           01 3f a6 f0 (00000001 00111111 10100110 11110000) (-257540351)
         *       4     4        (object header)                           26 00 00 00 (00100110 00000000 00000000 00000000) (38)
         *       8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
         *      12     4        (loss due to the next object alignment)
         * Instance size: 16 bytes
         * Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
         */
    }
}

对比下图
在这里插入图片描述
在这里插入图片描述

3.3.3 程序不会有锁的竞争

3.4 偏锁

3.4.1 单线程竞争

当线程A第一次竞争到锁时,通过操作修改Mark Work中的偏向线程ID、偏向模式。
如果不存在其他线程竞争,那么特有偏向锁的线程将永远不需要进行同步。
当一段同步代码一直被同一个线程多次访问,由于只有一个线程那么该线程在后续访问时便会自动获得锁
Hotspot的作者经过研究发现,多数情况下:
多线程的情况下,锁不紧不存在多线程的竞争,还存在锁由同一个线程多次获得的情况,偏向锁就是这种情况下出现的,它的出现是为了解决只有在一个线程执行同步时提高性能。
备注:偏向锁会偏向第一个访问锁的线程,如果在接下来的运行过程中,改锁没有被其他的线程访问,则持有偏向锁的线程将永远不需要触发同步。也即在偏向锁在资源没有竞争情况下消除了同步语句,懒的连cas操作都不做了,直接提高程序的性能。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.4.2 细化案例Account对象举例说明

在这里插入图片描述
在这里插入图片描述

3.4.3 偏向锁JVM命令

打印出java虚拟机初始化时所带的参数
java -XX:+PrintFlagsInitial |grep BiasedLock*
在这里插入图片描述
注意:偏向锁有延时,如果要用偏向锁,需要自己停滞4秒以上才能启动。若要看到效果修改4秒的延时为0秒
重要参数说明
在这里插入图片描述

3.4.4 无效果的code演示

package com.atguigu.springcloud.util.locktest;

import org.openjdk.jol.info.ClassLayout;

public class SynchronizedUpdemo {
    public static void main(String[] args) {
        Object o = new Object();
        synchronized (o){
            System.out.println(ClassLayout.parseInstance(o).toPrintable());
            /**
             * 上面的输出:15行01111000尾号是000,说明演示没有效果
             *
             * java.lang.Object object internals:
             *  OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
             *       0     4        (object header)                           78 f7 6f 5e (01111000 11110111 01101111 01011110) (1584396152)
             *       4     4        (object header)                           0f 00 00 00 (00001111 00000000 00000000 00000000) (15)
             *       8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
             *      12     4        (loss due to the next object alignment)
             * Instance size: 16 bytes
             * Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
             */
        }

    }
    private static void noLock(){

    }
}

3.4.5 原因是因为参数系统默认开启

在这里插入图片描述

3.4.6 关闭延时参数,启用该功能

在这里插入图片描述

3.4.7 在idea的这里添加此参数

Run->Eidt Configuartions->Modify options->add VM options
在这里插入图片描述
第二种方法看到效果是让程序延时超过4秒以上

package com.atguigu.springcloud.util.locktest;

import org.openjdk.jol.info.ClassLayout;

import java.util.concurrent.TimeUnit;

public class SynchronizedUpdemo {
    public static void main(String[] args) {
    	//故意暂定超过4秒以后也有同样的效果
        try {TimeUnit.SECONDS.sleep(5);}catch (InterruptedException e) {e.printStackTrace();}
        Object o = new Object();
        synchronized (o){
            System.out.println(ClassLayout.parseInstance(o).toPrintable());
        }
    }
    private static void noLock(){
    }
}

查看当前线程指针 第一种情况没有跟线程相关联
在这里插入图片描述
第二种情况跟线程相关
在这里插入图片描述

3.4.8 开始有第二个线程竞争资源

偏向锁的撤销:
1.当有另外线程逐步来竞争锁的时候,就不能再使用偏向锁的,要升级为轻量级锁
2.竞争线程尝试CAS更新为对象头失败,会等到全局安全点(此时不会执行任何代码)插销偏向锁。
在这里插入图片描述
在这里插入图片描述

3.4.9 总体步骤流程图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.5 轻锁

3.5.1 主要作用

有线程来参与锁的竞争,但是获取锁的冲突时间极短
本质就是自旋锁CAS

3.5.2 64位标记图

轻量锁最后两位是00
在这里插入图片描述

3.5.3 轻量级锁的获取

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.5.4 code

如果关闭偏向锁,就可以直接进入轻量级锁
-XX:-UseBiasedLocking
在这里插入图片描述

在这里插入图片描述

package com.atguigu.springcloud.util.interrup;

import org.openjdk.jol.info.ClassLayout;

public class SynchronizedUpDemo2 {
    public static void main(String[] args) {
        Object o = new Object();
        new Thread(()->{
            synchronized (o){
                System.out.println(ClassLayout.parseInstance(o).toPrintable());
            }
        },"t1").start();
        /**
         * 输出结果:
         * java.lang.Object object internals:
         *  OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
         *       0     4        (object header)                           70 f1 8f 7b (01110000 11110001 10001111 01111011) (2073031024)
         *       4     4        (object header)                           92 00 00 00 (10010010 00000000 00000000 00000000) (146)
         *       8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
         *      12     4        (loss due to the next object alignment)
         * Instance size: 16 bytes
         * Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
         */
    }
}

3.5.5 步骤流程图

在这里插入图片描述

3.5.6 自旋达到一定次数和程度

java6之前默认启用,默认情况下自旋的次数是10次
可以用-XX:PreBlockSpin=10来修改
或者自旋线程数超过cpu核数一半
java6之后自适应自旋锁的大致原理:
线程如果自旋成功了,那么下次自旋的最大次数会增加,因为JVM认为认为既然上次成功了,那么这一次也很大概率会成功。反之如果很少会自旋成功,那么下次会减少自旋的次数甚至不自旋,避免cpu空转。
自适应意味着自旋的次数不是固定不变的而是根据同一个锁上一次自旋的时间。拥有锁线程的状态来决定。

3.5.7 轻量锁与偏向锁的区别和不同

争夺轻量级锁失败时,自旋尝试抢占锁。轻量级锁每次退出同步块都要释放锁,而偏向锁是在竞争发生时才释放锁

3.6 重锁

有大量的线程参与锁的竞争,冲突性很高
锁标志位
在这里插入图片描述

Code
在这里插入图片描述

3.7 总结

3.7.1 锁升级发生后,hashcode去哪了?

在这里插入图片描述
在这里插入图片描述
code01:当一个对象已经计算过identity hash code,它就无法进入偏向锁状态,跳过偏向锁,直接升级轻量级锁
在这里插入图片描述
在这里插入图片描述
code02:偏向锁过程中遇到一致性哈希计算请求,立马撤销偏向模式,膨胀为重量级锁
在这里插入图片描述
在这里插入图片描述
各种锁优缺点、synchronized锁升级和实现原理
在这里插入图片描述
在这里插入图片描述

4 JIT编译器对锁的优化

JIT:Just In Time Compiler,一般翻译为即时编译器
锁消除

package com.atguigu.springcloud.util.interrup;

/**
 * 从JTI角度看相当于无视它,synchronized(o)不存在了
 * 这个锁对象并没有被公用扩散到其他线程使用
 * 极端的说就是根被没有加这个锁对象的底层机器码,消除了锁的使用
 */
public class SynchronizedUpDemo2 {
    static Object objectLock = new Object();
    public void m1(){
        /*synchronized (objectLock){
            System.out.println("-----hello LockClear");
        }*/
        //锁消除问题,JIT编译器会无视它,synchronized(0),每次new出来的就不存在了。非正常
        Object o  = new Object();
        synchronized (o){
            System.out.println("------hello LockClea"+"\t"+o.hashCode()+"\t"+objectLock.hashCode());
        }
    }
    public static void main(String[] args) {
        SynchronizedUpDemo2 synchronizedUpDemo2 = new SynchronizedUpDemo2();
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
               synchronizedUpDemo2.m1();
            },String.valueOf(i)).start();

        }
    }
}

结果:

------hello LockClea	2107224694	1935557557
------hello LockClea	900066040	1935557557
------hello LockClea	734582481	1935557557
------hello LockClea	1480952033	1935557557
------hello LockClea	835429761	1935557557
------hello LockClea	1830684002	1935557557
------hello LockClea	1510953719	1935557557
------hello LockClea	1420843554	1935557557
------hello LockClea	1810245172	1935557557
------hello LockClea	1736235642	1935557557

锁粗化

package com.atguigu.springcloud.util.interrup;

/**
 * 锁粗化
 * 假如方法中首位相接,前后相邻的都是同一个锁对象,那JIT编译器就会把这几个synchronized块合并成一个大块,
 * 加粗加大范围,一次申请锁使用即可,避免此次的申请和释放锁,提升了性能
 */
public class SynchronizedUpDemo2 {
    static Object objectLock = new Object();
    public static void main(String[] args) {
        new Thread(()->{
            synchronized (objectLock){
                System.out.println(1111);
            }
            synchronized (objectLock){
                System.out.println(2222);
                
            }
            synchronized (objectLock){
                System.out.println(3333);
            }
            synchronized (objectLock){
                System.out.println(4444);
            }
            synchronized (objectLock){
                System.out.println(5555);
            }
            //相当于这样
            synchronized (objectLock){
                System.out.println(1111);
                System.out.println(2222);
                System.out.println(3333);
                System.out.println(5555);
            }
        },"t1").start();
    }
}

小总结:
没有锁:自由自在
偏向锁:唯我独尊
轻量锁:楚汉争霸
重量锁:群雄逐鹿

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

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

相关文章

vivado 报错之procedural assignment to a non-register result is not permitted“

文章目录 这个错误通常是由于尝试在非寄存器类型的对象上进行过程赋值所引起的。在 Verilog 中&#xff0c;当使用 always 块时&#xff0c;其中的赋值操作应该只用于寄存器类型的变量&#xff0c;比如 reg 类型。非寄存器类型的信号&#xff08;比如 wire&#xff09;不能在 a…

如何将苹果手机照片导出?教你3个导出照片的必备技巧!

照片是我们记录生活&#xff0c;以及留下美好瞬间的最佳方式之一。通过手机照片&#xff0c;我们可以随时随地回忆过去的点点滴滴&#xff0c;还能将其分享给朋友和家人。因此&#xff0c;照片对于大家来说具有不可替代的价值与意义。 为了防止手机照片丢失&#xff0c;部分小…

WPF布局控件之WrapPanel布局

前言&#xff1a;博主文章仅用于学习、研究和交流目的&#xff0c;不足和错误之处在所难免&#xff0c;希望大家能够批评指出&#xff0c;博主核实后马上更改。 概述&#xff1a; 后续排序按照从上至下或从右至左的顺序进行&#xff0c;具体取决于方向属性的值。WrapPanel 位…

beego模板解析报错

文章目录 前言解决beego解析问题总结 前言 网上搜索为模板解析路径问题&#xff0c;实际是beego解析vue打包后的index.html出现错误&#xff0c; 比如解决时排除了.go代码&#xff0c;发现没问题&#xff0c;运行beego打印,打开浏览器进入web时发现wen打不开&#xff0c;并在b…

支付宝本地生活团购服务商如何申请?两个方法教给你

支付开宝的本地生活来了&#xff01;按支付宝财大气粗的做法&#xff0c;它一旦要推什么项目&#xff0c;那自然会在前期疯狂洒钱&#xff0c;以求通过这种模式快速占领市场。 所以&#xff0c;这次支付宝要推本地生活项目&#xff0c;这一贯做法自然得跟上&#xff0c;只是这…

2024上海国际人工智能展(CSITF)“创新驱动发展·科技引领未来”

人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;作为当今世界科技发展的关键领域之一&#xff0c;正不断推动着各行各业的创新和变革。作为世界上最大的消费市场之一&#xff0c;中国正在积极努力将AI技术与产业融合并加速推广应用。在这个背景下&…

基于Chirp窄带扩频技术的无线混合组网应用,以多角色智能计量插座作为Chirp广域基站,构建边缘计算混合无线网络

随着物联网&#xff08;IoT&#xff09;的不断发展&#xff0c;无线通信技术的需求也在不断增加。Chirp窄带扩频技术是一种具有广泛应用潜力的无线通信技术&#xff0c;它在低功耗、广域覆盖、抗干扰等方面具备独特的优势。本文介绍了如何利用磐启微Chirp技术构建ECWAN无线混合…

混合式ANC主动降噪耳机系统设计(含C源代码)

混合式ANC主动降噪耳机系统设计(含C源代码) 是否需要申请加入数字音频系统研究开发交流答疑群(课题组)?可加我微信hezkz17, 本群提供音频技术答疑服务,+群赠送语音信号处理降噪算法,蓝牙音频,DSP音频项目核心开发资料, 1 FF信号链路与FB 链路算法处理上一样 X(n)为噪声输…

强化学习的动态规划

一、动态规划 动态规划&#xff08;DP&#xff09;一词指的是一系列算法&#xff0c;这些算法可用于在给定环境的完美模型作为马尔可夫决策过程&#xff08;MDP&#xff09;的情况下计算最优策略。经典的DP算法在强化学习中具有有限的实用性&#xff0c;既因为其对完美模型的假…

【ElasticSearch系列-04】ElasticSearch的聚合查询操作

ElasticSearch系列整体栏目 内容链接地址【一】ElasticSearch下载和安装https://zhenghuisheng.blog.csdn.net/article/details/129260827【二】ElasticSearch概念和基本操作https://blog.csdn.net/zhenghuishengq/article/details/134121631【三】ElasticSearch的高级查询Quer…

迅为iTOP-RK3568开发板npu手册更新

iTOP -RK3568开发板使用教程更新&#xff0c;后续资料会不断更新&#xff0c;不断完善&#xff0c;帮助用户快速入门&#xff0c;大大提升研发速度。 为了满足人工智能的需要&#xff0c;去年&#xff0c;迅为基于RK3568开发板编写了对应的手册文档>>>【资料上新】基…

K7系列FPGA进行FLASH读写1——CCLK控制(STARTUPE2原语)

最近的工作涉及对 FPGA 进行远程更新&#xff0c;也就是通过远程通信接口将 .bin 文件送到 FPGA&#xff0c;然后写入 FLASH&#xff0c;这样当 FPGA 重新上电后就可以执行更新后的程序了。因此第一步工作就是进行 FLASH 的读写控制。 然而如果尝试配置 FLASH 管脚时&#xff0…

队列、循环队列和双端队列

目录 1、队列 1.1 概念 2.2 队列的使用 2.3 队列模拟实现 2、循环队列 2.1 循环队列的认识 2.2 设计循环队列 3. 双端队列 (Deque) 1、队列 1.1 概念 队列 &#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列…

Python之Excel——复制一个sheet当做模板,生成多个sheet

目录 专栏导读背景思路1、加载模板2、项目文件2、完整版代码:3、视频演示:4、总结:&#x1f44d; 该系列文章专栏&#xff1a;[Python办公自动化专栏] 专栏导读 &#x1f338; 欢迎来到Python办公自动化专栏—Python处理办公问题&#xff0c;解放您的双手 &#x1f3f3;️‍&…

synchronized和死锁介绍

synchronized特性synchronized使用修饰普通方法(对象锁)修饰静态方法&#xff08;类锁&#xff09;修饰代码块&#xff08;明确指定锁的对象&#xff09;非锁竞争情况 死锁死锁是什么&#xff1f;死锁的必要条件循环等待场景程序死锁怎么排除死锁问题怎么解决 标准库的线程安全…

led驱动电源模块能进行自动化测试吗,具体测试方法,流程是?

LED电源模块测试的痛点主要包括以下几点&#xff1a; 测试效率低&#xff1a;传统的LED电源模块测试方法通常采用人工操作&#xff0c;测试效率低下&#xff0c;且易出错。 测试项目不全面&#xff1a;传统的测试方法可能无法覆盖所有的性能指标&#xff0c;导致一些潜在的问…

非洲“支付宝”PalmPay搭载OceanBase:成本降低80%

10 月 30 日&#xff0c;非洲支付公司PalmPay 的核心系统搭载国产自研数据库OceanBase&#xff0c;正式投入使用。PalmPay 也是 OceanBase 首个非洲商业用户。 作为一家非洲领先的金融科技公司&#xff0c;PalmPay 于 2019 年在尼日利亚推出电子钱包应用&#xff0c;其功能类似…

Verilog刷题[hdlbits] :Module cseladd

题目&#xff1a;Module cseladd One drawback of the ripple carry adder (See previous exercise) is that the delay for an adder to compute the carry out (from the carry-in, in the worst case) is fairly slow, and the second-stage adder cannot begin computing …

推荐PHP匿名在线聊天室系统源码

PHP匿名在线聊天室系统源码 自适应PCWAP端 可发语音、图片&#xff0c;修改数据库config\settings.php可拿去搭建专门跟客户聊天的网站。 演示地址&#xff1a;runruncode.com/php/19610.html

AD教程(五)光耦及二极管元件模型的创建

AD教程&#xff08;五&#xff09;光耦及二极管元件模型的创建 二极管元件的创建 放置管脚&#xff0c;设置管脚号和管脚名称&#xff08;一般隐藏&#xff09;绘制三角形 右键放置直线&#xff0c;选择放置多边形&#xff0c;操作逻辑&#xff0c;每次操作都会增加一边&…