Synchronzied 的深入理解 (上)

脑机接口(BCI)从原理到开发实战 01|意念控制真的来了?一文看懂脑机接口的技术革命 类型定义典型应用主动式用户主动产生特定思维模式来控制设备运动想象(想象左手/右手移动)反应式用户被动接受外部刺激,系统检测大脑反应P300拼写器、SSVEP(稳态视觉诱发电位)被动式系统监测用户自发脑状态,不要求主动控制疲劳监测、情绪识别、注意力评估本系列后续文章将重点围绕主动式(运动想象)和反应式(P300/SSVEP)展开实战。脑机接口,这个曾经只存在于科幻中的概念,正在政策、资本、技术的三重驱动下,加速从实验室走向产业落地。2026年,注定是脑机接口发展史上浓墨重彩的一年。 阅读详情
为什么要使用多线程

在硬件条件不断进步的今天,我们现在常用的电脑已经不是简单的单核CPU,而是4核、8核、甚至更多。

而如果不使用多线程技术的话,一般我们就只用一个CPU来处理程序上的计算问题,复杂且庞大的计算量全部压在一个CPU上,其它CPU只负责划水,那么这无法物尽其用。

当然我们也不是说可怜这一个CPU,而是真实的环境下,使用多核CPU以及超线程技术可以实现并行,这意味着我们可以在单位时间内处理更多的请求,提升吞吐量。

多线程带来的安全性问题

一个技术的提出,有好处当然也有弊端。虽然多线程技术可以让吞吐量提升,但是多线程技术在运用中会带来许多安全性问题,一个比较常见的就是对共享数据的访问

我们知道,每个线程单独独立,因为他们拥有自己的内存空间,彼此不干扰,那么当两个没有任何关系的线程去对同时一个值进行修改的时候,谁先谁后?谁又能够保证谁拿到的是修改后的值呢?如果修改了,其它线程是否可以及时拿到更新后的值呢?

这里是不是有点像数据库中,脏读的概念呢?

在这里插入图片描述
两个线程同时对变量i进行++操作的结果,是否是我们所期待的3呢?

对于线程安全性,本质上是管理对于数据状态的访问,同时数据状态需要满足两个条件。

  • 共享的,这个数据能够被多个线程访问到
  • 可变的,这个数据在的生命周期可以被改变

那如果一个对象,不需要我们使用其他一些同步手段,或者一些协助的请下,依旧可以达到预期结果的话,就意味着这个对象是线程安全的。

对于上面的例子而言,如果两个线程同时去修改i的值,并且最后i的结果是3的话,那么说明这个数据是线程安全的,如果结果不为3的话,说明这个数据没有达到我们的预期结果,意味着这个数据不是线程安全,我们就需要一些同步的手段,来促使他达到我们预期的结果3。

public class ThreadDemo {

    private static int count = 0;

    public static void main(String[] args) throws InterruptedException {

        for(int i =0;i<1000;i++){

            new Thread(()->{


                try {
                    Thread.sleep(2);//让他改变的时候多延迟一下
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                count ++; // 1000 个线程将会对这个count进行数值修改
            }).start();

        }
        Thread.sleep(3000);
        System.out.println(count);
    }

}

在这里插入图片描述

以上代码多测试几遍,你会发现有些结果会与1000有些差别,倘若这个问题,出现在线上的话,例如汇总分析的数值总是有差池,你的领导务必会找你的麻烦。

那么此时,我们可以认为这个count线程不安全的。

如何解决线程并行时所带来的数据安全性问题?

我们可以将运行时的程序看做是一个食堂,每个线程想象成学生,1000个学生争先恐后地冲进食堂,并且数百只手向你索要饭菜时候的样子,场面肯定很混乱,而且人数的拥堵会造成汤水洒一地,或者踩踏事件。

那么这个时候我们很容易想到,为什么你们不排队呢?

这也很顺其自然的想到,我们可不可以将线程从某个时间由并行转变成串行,来保证有序呢,这样既安全,每个人都可以得到满意的菜品。

这就引入了一个概念,锁

Sychronzied

通过synchronized关键字,我们可以对我们希望的有序的地方进行声明,来达到数据的安全性。sychronzied可以修饰在什么地方?

public class SychronizedDemo {

    public synchronized void demo(){}
    
    public static synchronized  void demo2(){}

    public void demo3(){

        synchronized (this){
            // todo
        }

    }

    public void demo4(){
        synchronized (SychronizedDemo.class){
            // todo
        }
    }
}
  • demo
    • 当我们用于修饰实例方法的时候,意味着这个方法在被访问的时候,必须获得这个实例的锁,才可以进入同步代码。
  • demo2
    • 用于修饰静态代码的时候,只有获得这个类对象的锁才可以访问,因为对于类文件.class,jvm中有且只有一份,所以这样可以保证锁的唯一性。
  • demo3
    • 本质上和demo是一样的,不过可以控制的粒度更小,同步代码块的前面和后面都可以随意反问,但是想要进入代码块必须获得当前实例对象的锁。
  • demo4
    • 锁与demo2相同,粒度与demo3相同。

我们先来看看,加了synchronized的例子是否能够达到我们的预期值。

public class SychronziedThreadDemo {

    private static int count = 0;

    public static void main(String[] args) throws InterruptedException {

        for(int i =0;i<1000;i++){

            new Thread(()->{
                synchronized(SychronziedThreadDemo.class){
                    try {
                        Thread.sleep(2);//让他改变的时候多延迟一下
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    count ++; // 1000 个线程将会对这个count进行数值修改
                }
            }).start();

        }
        Thread.sleep(3000);
        System.out.println(count);
    }

}

在这里插入图片描述

1000,这就是我们预期的结果,为什么只是加了这样简单的一句话,就能够解决数据安全性问题呢?

Sychronized 中的锁

我们使用sychronzied关键字的时候,好像并没有使用任何锁的语法,起码没有这种

Lock lock = new Lock();

如上的写法。

比较可疑的就是sychonrzied(...)括号里的东西,值得我们思考。

但因为sychronized是一个关键字,具体的实现,我们通过阅读Hotspot源码才能知道这个关键字到底底层是如何被解释的。

这个先不急,我们来理解一下括号里的东西的意义。

sychonrzied关键后面的东西确实可以被称之为锁,但是我觉得这个在当前的场景,被称为锁对象更为合理。

为什么我要这样说呢,从上面的sychronzied使用方法不难看出,除了可以用同步代码块来缩小锁的范围,使用不同的生命周期的对象也可以控制锁的范围,如果是实例对象,那么你锁住的就是当前这个实例对象,如果你又重新new了另外一个对象,上一个锁对这个对象就没有多大影响,因为是完全不同的实例对象,但是类对象却不一样,因为只有这一份,即便你new了再多对象也可以保证用的是同一把锁。

看到这里估计又有疑问了,对象和锁到底是什么关系?好像是个对象就可以成为锁一样。

更多的锁信息

锁可以保证我们并行成为串行,像是在电话亭等电话,如果进入电话亭的人不离开电话亭你是无法进去的,因为那里太狭窄,只能容下一个人。

那么这就有锁的一个很重要的特性->互斥特性

  • 我们的锁需要一个标志来表示,当前锁的状态,是被独占了,还是被释放了,还是并没有上锁。后面的线程可以根据这个锁的状态来判断自己是应该竞争锁,还是被阻塞。
  • 同时,这个状态因为被多个线程都是可见的。

想要探索这些,我们就必须知道对象在内存中到底是如何存储的,因为在java层面,我们除了synchronzied这几个英文字母看不出更多信息了。

对象在内存中的布局

在Hotspot虚拟机中,对象在内存中的存储布局,可以分为三个部分

  • 对象头(Header)
  • 实例数据(Instance Data)
  • 对齐填充(Padding)

在这里插入图片描述
我们在这里仿佛看到了锁的影子。

由于篇幅可能过长,这边分为上下两章,请关注后续更新。

每天积累一点点

杰理可视化SDK开发-杰理AC1123N芯片SDK开发笔记合集 该文档主要描述 AC112N开发相关的使用说明和注意事项,收集并持续更新开发调试过程中的相关疑问和解答,对SDK介绍文档做一个补充说明。写作人:李永奉,参考项目MD-026H; AC112N-SDK项目帮助文档在杰理开发者平台(JL DP)'帮助'处进入,如本文档有与后续帮助文档或工具注释说明冲突,以后者为标准。 阅读详情

相关推荐

gmsv源代码c语言,石器时代ABLua的原理、简介、过程、运用、收发

操作原理(一)服务端:服务器源文件客户端:客户所操作的程序(既是游戏客户端)接口:既是某项功能(例如:鼠标点击,文字发送,战斗,观战,人物动作等)返回的值ABlua:在源代码中添加的整套引擎作为回调接口--lua所实现的功能是基于服务端源码添加的接口由该接口与客户端发送封包实现功能源码里是否有ABlua回调接口?例如:源码里的gmsv/battle.c文件(既是战斗回调文件)以下为简单描述C给予l...

weixin_35223575的博客 2408

synchronized用法详解

synchronized 是 Java 中的关键字,是一种同步锁。主要应用于多线程环境下保证线程的安全性。A. 无论synchronized关键字加在方法上还是对象上,如果它作用的对象是非静态的,则它取得的锁是对象;如果synchronized作用的对象是一个静态方法或一个类,则它取得的锁是对类,该类所有的对象同一把锁。B. 每个对象只有一个锁(lock)与之相关联,谁拿到这个锁谁就可以运行它所控制的那段代码。C. 实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。

qq_43842093的博客 7681

ADRV902x射频评估实战:手把手教你用TES GUI生成ARM bin与JESD204C配置文件

在射频前端系统设计中,ADRV902x系列收发器凭借其宽带性能和灵活配置能力,已成为5G基站、微波回传等场景的核心器件。然而当工程师面对非官方硬件平台时,如何高效利用Transceiver Evaluation Software(TES)完成关键配置,成为项目推进的第一道门槛。本文将彻底解析脱离ADS9母板后的完整离线工作流,从参数预设到文件生成,手把手解决真实工程中的配置痛点。在Demo模式下,所有硬件状态检测都会被跳过,但配置文件生成功能完全可用。作为基础模板,因其配置最为简洁,便于后续自定义修改。

weixin_33704591的博客 429

详解synchronized与Lock的区别与使用

引言: 昨天在学习别人分享的面试经验时,看到Lock的使用。想起自己在上次面试也遇到了synchronized与Lock的区别与使用。于是,我整理了两者的区别和使用情况,同时,对synchronized的使用过程一些常见问题的总结,最后是参照源码和说明文档,对Lock的使用写了几个简单的Demo。请大家批评指正。 12 技术点: 1、线程与进程: 在开始之前先把进程与线程进行区分一

Barry的博客 1013

中标麒麟,postgres报错invalid value for parameter "timeZone":"Asia/Beijing"

在中标麒麟服务器上,安装postgres,启动tomcat容器时,报invalid value for parameter "timeZone":"Asia/Beijing"。 查看postgres运行日志,也报同样的错误。 报错原因:服务器的时区,在Postgres支持的时区目录中找不到。当时在服务器上信息为Beijing 解决步骤: 1. cat /etc/sysconfig/cloc

u010213931的博客 7924

告别Keil?在Mac上配置STM32CubeIDE + CMSIS-DAP调试器全攻略(含常见报错解决)

本文详细介绍了在Mac平台上配置STM32CubeIDE与CMSIS-DAP调试器的全流程,包括硬件准备、软件安装、工程创建及调试优化。通过实战指南,帮助开发者高效完成STM32开发,解决常见报错问题,提升开发效率。

weixin_30485379的博客 432

Sychronized底层原理及特性详解

特性 原子性 ​ 原子性就是一个操作或者多个操作要么一起执行,要么不执行。比如i++就是不具备原子性,它是先取出i的数据再进行加1,那这个过程在多线程中可能会出现脏读的情况。(Volatile与Sychronized的最大区别就是不具备原子性) 可见性 ​ Sychronzied被加锁对象的锁对于每个线程都是可见的,都能获取到锁的状态,在释放锁之前,会把最新的值更新到主存,保证值都是最新状态。 ​ Volatile修饰的变量,每当值要改变时,都会立即更新到主存中,主存的内容对于其他线程都是可见的,就能保证值

a15119273009的博客 1418

树莓派34/100 - Pico读取MPU6050加速度和陀螺仪传感器数据

树莓派Pico连接MPU-6050模块(三轴陀螺仪+三轴加速度),读取运动姿态数据。

申龙斌的程序人生 5088

SychronousQueue同步队列

SynchronousQueue由于其独有的线程一一配对通信机制,在大部分平常开发中,可能都不太会用到,但线程池技术中会有所使用,由于内部没有使用AQS,而是直接使用CAS,所以代码理解起来会比较困难,但这并不妨碍我们理解底层的实现模型,在理解了模型的基础上,有兴趣的话再查阅源码,就会有方向感,看起来也会比较容易,希望本文有所借鉴意义。总结下来就是:队尾匹配队头出队,先进先出,体现公平原则。2、接着,线程put2执行了put(2)操作,跟前面一样,put2线程入队列,自旋一小会后睡眠等待,这时队列。

2301_78102191的博客 1156

保姆级教程:用K210麦克风阵列模块实现声源定位(附完整Python代码与坐标计算)

本教程详细介绍了如何使用K210麦克风阵列模块实现高精度声源定位,包括硬件连接、算法解析与实战代码。通过Python代码示例,展示了从原始数据获取到三维空间坐标计算的完整流程,适用于智能家居、机器人导航等场景。

weixin_42558093的博客 226

《小白入门:无人机电调 ESC 的 PWM 接口特性、主流协议与使用指南》

电调是无人机的 “动力中枢”,其 PWM 接口是入门的基础,而 SBUS、DroneCAN 等协议则代表了更高阶的控制方式。小白学习时,需先掌握 PWM 的基本特性和连接方法,再根据场景选择合适的协议,同时严格遵守使用注意事项(如电源匹配、校准步骤、安全操作)。随着实践深入,逐步理解 “协议差异” 和 “系统协同”,才能让无人机更稳定、安全地飞行。

bother3000的博客 3768

编程英语词汇汇总

关于计算机基础: software 软件 computer 计算机 Operating System 操作系统(简称OS) DOS(Disk Operating System)硬盘操作系统 关于编程:

weixin_45523449的博客 1301

Agent Harness Engineering: AI Agent 执行管控与安全沙箱 原理与最佳实践

我们正站在计算范式转移的历史节点上。2024-2026 年间,AI 系统从被动的内容生成器(Generative AI)演变为主动的行动执行者(Agentic AI)。这一转变的根本特征是:根据 2026 年初的行业数据:然而,能力的提升伴随着风险的指数级增长。2024-2026 年间发生的多起标志性安全事件揭示了 Agent 系统的脆弱性:案例 1:Slack AI 数据外泄事件(2024 年 8 月)案例 2:制造业供应链攻击(2026 年 Q3)案例 3:Arup 深度诈骗案(2026 年 9 月)这

AI天才研究院 1668

Synchronzied 的深入理解(下)

Sychronized深入分析 话接上文,我们需要想要知道为什么所有的对象都可以成为sychronized的锁,然后有一张描述对象在内存中的布局。 首先对于Java而言,我们创建实例的方法可以通过new一个对象,而对于JVM而言,这句话会被解释成,创建一个instanceOopDesc对象,虚拟机使用OOP-KLASS模型来描述Java对象实例。 OOP(Ordinary Object Poi...

CandyCCCation的博客 411

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

深入理解synchronzied,底层源码剖析

synchronzied底层原理,优化

cloud_fly的博客 1298

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

【得物技术】深入理解synchronzied底层原理

一、synchronized 简介 synchronized 是 Java 中的关键字,是一种同步锁。在多线程编程中,有可能会出现多个线程同时争抢同一个共享资源的情况,这个资源一般被称为临界资源。这种共享资源可以被多个线程同时访问,且又可以同时被多个线程修改,然而线程的执行是需要 CPU 的资源调度,其过程是不可控的,所以需要采用一种同步机制来控制对共享资源的访问,于是线程同步锁——synchronized 就应运而生了。 二、如何解决线程并发安全问题 多线程并发读写访问临界资源的情况下,是会存在线程

SmartCodeTech的博客 717

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

深入研究 Java Synchronize 和 Lock 的区别与用法

在分布式开发中,锁是线程控制的重要途径。Java为此也提供了2种锁机制,synchronized和lock。做为Java爱好者,自然少不了对比一下这2种机制,也能从中学到些分布式开发需要注意的地方。   我们先从最简单的入手,逐步分析这2种的区别。   一、synchronized和lock的用法区别   synchronized:在需要同步的对象中加入此控制,synchronized

natian306的专栏 8万+

Java 线程以及sychronizd同步

1.使用情况:在多线程的情况下需要用到,比如public static变量,某一时刻只能一个线程进行操作并改变它的值,要用这个关键字来约束。来保证线程安全 2.简介: 并发的基础知识 什么是线程? 线程有时称为 轻量级进程。与进程一样,它们拥有通过程序运行的独立的并发路径,并且每个线程都有自己的程序计数器,称为堆栈和本地变量。然而,线程存在于进程中,它们与同一进程内的其他线程

Jerry's Home 2631

synchronzied和lock的原理及区别

在讲sychronzied和lock之前,首先了解下java中“锁”这个重要的东西。 锁,顾名思义,就是把一块可访问的资源“锁”住,禁止别人使用。 锁是多线程高并发操作的重要控制手段。它可以把多线程同时访问的同一资源(又称临界区)锁住,控制资源仅且只有一个线程可以访问,目的就是为了避免造成读脏数据等等问题,得到意想不到的结果。 相信大家对锁的概念都有一定的认知。接下来我们聊聊synchron...

qq_39024365的博客 994

java 多线程之Sychronization的三种使用情况

java 多线程之Sychronization的三种使用情况  1.同步代码块     锁对象可以是任意的对象  2.普通同步方法 锁对象默认是是 this  3.静态同步方法 锁对象是当前类的class对象 测试类如下: package Sychronization; /**  * 测试类  * @author feige  */ public class Sychroniz

飞升飞的博客 4836

Synchronzied底层实现

synchronized的底层是使用操作系统的mutex lock实现; Mutex Lock 监视器锁(Monitor)本质是依赖于底层操作系统的Mutex Lock(互斥锁)来实现的。每个对象都对应于一个可称为” 互斥锁” 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象; 互斥锁:用于保护临界区,确保同一时间只有一个线程访问数据。对共享资源的访问,先对互斥量进行加锁,如...

luoyoub的博客 473

sychrongized 关键字

sychrongized关键字

qq_58309003的博客 732

Sychronized、Lock、Volatile、原子类

    同步的时候非同步也可以同时执行.   一、内置锁Synchronized: 1、概念 synchronized同步的不是一个代码块,而是一个对象。static的话是class对象。 一个加锁的原则是对不变性加锁:不变性条件中涉及的所有变量都需要由同一个锁来保护。 居有三大特性:有序性,原子性,可见性 不要使用双重锁定,因为JAVA内存模型允许所谓的“无序写入”。 线程对...

ibinbinb的博客 583

Syschronized的底层实现原理以及各种锁的理解

java中每个对象都可作为锁,锁有四种级别,按照量级从轻到重分为:无锁、偏向锁、轻量级锁、重量级锁。每个对象一开始都是无锁的,随着线程间争夺锁,越激烈,锁的级别越高,并且锁只能升级不能降级。 java对象头  锁的实现机制与java对象头息息相关,锁的所有信息,都记录在java的对象头中。用2字(32位JVM中1字=32bit=4baye)存储对象头,如果是数组类型使用3字存储(还需存储数组长度)。对象头中记录了hash值、GC年龄、锁的状态、线程拥有者、类元数据的指针。 Syschron..

做的过程自我总结 1011

sychronized实现原理

测试类: 打开cmd,执行javac  java文件的路径进行编译该文件,生成.class文件,然后执行javap -c生成的.class文件反编译.class文件,-c表示打印出方法的字节码指令,结果如下 发现有俩个监视类的东西,monitorenter,monitorexit,在线查看jvm规范,描述如下 大致翻译就是 monitorenter 获取由objec

wenwen360360的博客 921

sychronized与lock的区别

sychronized是java的关键字,而lock是一个类 sychronized获取锁的时候,假设A线程获得锁,B线程等待,若A阻塞,B会一直等待;而lock在这种情况下B会尝试去获取锁 sychronized的锁的状态是无法判断的,而lock是可以判断的 sychronized与lock都是对象锁,都支持重入锁 lock可以实现sychronized不具备的特性,如响应中断,支持超时...

weixin_43573534的博客 1389
上一篇: 线程的应用
下一篇: Synchronzied 的深入理解(下)
PopCandier
博客等级 码龄9年 19粉丝 17原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值