【并发编程】Synchronized的使用

📫作者简介:小明java问道之路2022年度博客之星全国TOP3,专注于后端、中间件、计算机底层、架构设计演进与稳定性建设优化,文章内容兼具广度、深度、大厂技术方案,对待技术喜欢推理加验证,就职于知名金融公司后端高级工程师。

        

📫 热衷分享,喜欢原创~ 关注我会给你带来一些不一样的认知和成长。

        

🏆 2022博客之星TOP3 | CSDN博客专家 | 后端领域优质创作者 | CSDN内容合伙人

🏆 InfoQ(极客邦)签约作者、阿里云专家 | 签约博主、51CTO专家 | TOP红人、华为云享专家

        

🔥如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主~ 


🍅 文末获取联系 🍅  👇🏻 精彩专栏推荐订阅收藏 👇🏻

专栏系列(点击解锁)

学习路线(点击解锁)

知识定位

🔥Redis从入门到精通与实战🔥

Redis从入门到精通与实战

围绕原理源码讲解Redis面试知识点与实战

🔥MySQL从入门到精通🔥

MySQL从入门到精通

全面讲解MySQL知识与企业级MySQL实战

🔥计算机底层原理🔥

深入理解计算机系统CSAPP

以深入理解计算机系统为基石,构件计算机体系和计算机思维

Linux内核源码解析

围绕Linux内核讲解计算机底层原理与并发

🔥数据结构与企业题库精讲🔥

数据结构与企业题库精讲

结合工作经验深入浅出,适合各层次,笔试面试算法题精讲

🔥互联网架构分析与实战🔥

企业系统架构分析实践与落地

行业最前沿视角,专注于技术架构升级路线、架构实践

互联网企业防资损实践

互联网金融公司的防资损方法论、代码与实践

🔥Java全栈白宝书🔥

精通Java8与函数式编程

本专栏以实战为基础,逐步深入Java8以及未来的编程模式

深入理解JVM

详细介绍内存区域、字节码、方法底层,类加载和GC等知识

深入理解高并发编程

深入Liunx内核、汇编、C++全方位理解并发编程

Spring源码分析

Spring核心七IOC/AOP等源码分析

MyBatis源码分析

MyBatis核心源码分析

Java核心技术

只讲Java核心技术

本文目录

本文导读

一、synchronized的三种应用方式

二、synchronized作用于实例方法

三、synchronized作用于静态方法

四、synchronized作用于同步代码块

总结


本文导读

在并发编程中存在线程安全问题,主要原因有一是.存在共享数据,二是多线程共同操作共享数据。

synchronized是Java的一个关键字,它能够将代码块/方法锁起来是一种互斥锁,一次只能允许一个线程进入被锁住的代码块。synchronized是Java中解决并发问题的一种最常用最简单的方法 ,他可以确保线程互斥的访问同步代码。

一、synchronized的三种应用方式

Java中每一个对象都可以作为锁,这是synchronized实现同步的基础。

如果synchronized修饰的是实例方法,对应的锁则是对象实例,进入同步代码前要获得当前实例的锁

如果synchronized修饰的是静态方法,对应的锁则是当前类的Class实例,进入同步代码前要获得当前类对象的锁

如果synchronized修饰的是代码块,对应的锁则是传入synchronized的对象实例(锁是括号里面的对象),对给定对象加锁,进入同步代码库前要获得给定对象的锁

二、synchronized作用于实例方法

​1、多个线程访问同一个对象的同一个方法,只有一个线程能够抢到锁,因为一个对象只有一把锁,一个线程获取了该对象的锁之后,其他线程无法获取该对象的锁,就不能访问该对象的其他synchronized实例方法

2、一个线程获取了该对象的锁之后,其他线程来访问其他synchronized实例方法,其他线程来访问synchronized修饰的其他方法时需要等待线程1先把锁释放

3、一个线程获取了该对象的锁之后,其他线程来访问其他非synchronized实例方法,是可以访问的

4、当多个线程作用于不同的对象,因为两个线程作用于不同的对象,获得的是不同的锁,所以互相并不影响

public class SynchronizedTest implements Runnable {
    // 共享资源
    static int i =0;

    // synchronized 修饰实例方法
    public synchronized void increase() {
        i++;
    }

    @Override
    public void run(){
        for (int j =0 ; j<10000;j++)
            increase();
    }

    public static void main(String[] args) throws InterruptedException {
        SynchronizedTest test = new SynchronizedTest();
        Thread t1 = new Thread(test);
        Thread t2 = new Thread(test);
        t1.start();
        t2.start();
    }
}

三、synchronized作用于静态方法

两个线程实例化两个不同的对象,但是访问的方法是静态的,两个线程发生了互斥(即一个线程访问,另一个线程只能等待)。

因为静态方法是依附于类而不是对象的,当synchronized修饰静态方法时,锁是class对象

public class SynchronizedTest implements Runnable {
    static int i =0;

    // synchronized 修饰实例方法
    public static synchronized void increase(){
        i++;
    }

    @Override
    public void run(){
        for (int j =0 ; j<10000;j++)
            increase();
    }

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new SynchronizedTest ());
        Thread t2 = new Thread(new SynchronizedTest ());
        t1.start();
        t2.start();
    }
}

四、synchronized作用于同步代码块

方法比较大,同时存在一些比较耗时的操作,而需要同步的代码又只有一小部分,此时我们可以使用同步代码块的方式对需要同步的代码进行包裹。

将synchronized作用于一个给定的实例对象instance,即当前实例对象就是锁对象,每次当线程进入synchronized包裹的代码块时就会要求当前线程持有instance实例对象锁,如果当前有其他线程正持有该对象锁,那么新到的线程就必须等待。

除了instance作为对象外,我们还可以使用this对象(代表当前实例)或者当前类的class对象作为锁。

// this,当前实例对象锁
synchronized(this) {
    for(int j=0;j<1000000;j++)
        i++;
}

// class对象锁
synchronized(SynchronizedTest.class) {
    for(int j=0;j<1000000;j++)
        i++;
}

总结

如果synchronized修饰的是实例方法,对应的锁则是对象实例,进入同步代码前要获得当前实例的锁

如果synchronized修饰的是静态方法,对应的锁则是当前类的Class实例,进入同步代码前要获得当前类对象的锁

如果synchronized修饰的是代码块,对应的锁则是传入synchronized的对象实例(锁是括号里面的对象),对给定对象加锁,进入同步代码库前要获得给定对象的锁

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

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

相关文章

K8S基础笔记

1、namespace 名称空间用来对集群资源进行隔离划分&#xff0c;默认只隔离资源&#xff0c;不隔离网络k8s默认的名称空间为default 查看k8s的所有命名空间 kubectl get namespace 或者 kubectl get ns 创建名称空间 kubectl create ns 名称 或使用yaml方式 编写yamlkub…

【计算机视觉】24-Object Detection

文章目录 24-Object Detection1. Introduction2. Methods2.1 Sliding Window2.2 R-CNN: Region-Based CNN2.3 Fast R-CNN2.4 Faster R-CNN: Learnable Region Proposals2.5 Results of objects detection 3. SummaryReference 24-Object Detection 1. Introduction Task Defin…

Java code auditing

1) FindBugs Checkstyle PMD 2) OWASP ZAP Burp Suite (XSS漏洞) 3) SQL注入

力扣-414.第三大的数(两种解法)

文章目录 第三大的数解法一&#xff08;排序加遍历对比&#xff09;解法二&#xff08;遍历一遍加迭代&#xff09; 第三大的数 题目&#xff1a; 给你一个非空数组&#xff0c;返回此数组中第三大的数 。如果不存在&#xff0c;则返回数组中最大的数。 示例 1&#xff1a; 输…

Python---函数的嵌套(一个函数里面又调用了另外一个函数)

函数嵌套调用------就是一个函数里面又调用了另外一个函数。 基本语法&#xff1a; # 定义 函数B def funcB():print(这是funcB函数的函数体部分...)# 定义 函数A def funcA():print(- * 80) # 这一行为了更好区分print(这是funcA函数的函数体部分...)# 假设我们在调用funcA…

HDD与QLC SSD深度对比:功耗与存储密度的终极较量

在当今数据世界中&#xff0c;存储设备的选择对于整体系统性能和能耗有着至关重要的影响。硬盘HDD和大容量QLC SSD是两种主流的存储设备&#xff0c;而它们在功耗方面的表现是许多用户关注的焦点。 扩展阅读&#xff1a; 1.面对SSD的步步紧逼&#xff0c;HDD依然奋斗不息 2.…

OceanBase 4.2.1 LTS 发版 | 一体化数据库首个长期支持版本

在刚刚结束的年度发布会上&#xff0c;OceanBase 沿着“一体化”产品战略思路&#xff0c;发布了一体化数据库的首个长期支持版本 4.2.1 LTS。作为 4.0 系列的第一个 LTS 版本&#xff0c;该版本的定位是支撑客户关键业务稳定长久运行&#xff0c;我们非常认真的打磨了这个版本…

【Python】给定一个长度为n的数列,将这个数列按从小到大的顺序排列。1<=n<=200

2、问题描述 给定一个长度为n的数列&#xff0c;将这个数列按从小到大的顺序排列。1<n<200 样例输入 5 8 3 6 4 9 样例输出 3 4 6 8 9 n int(input()) a list(map(int,input().split())) a.sort() for i in a:print(i,end ) 运行结果&#xff1a;

AIGC 技术在淘淘秀场景的探索与实践

本文介绍了AIGC相关领域的爆发式增长&#xff0c;并探讨了淘宝秀秀(AI买家秀)的设计思路和技术方案。文章涵盖了图像生成、仿真形象生成和换背景方案&#xff0c;以及模型流程串联等关键技术。 文章还介绍了淘淘秀的使用流程和遇到的问题及处理方法。最后&#xff0c;文章展望…

云桌面 node_modules 切换艰辛历程记录 rebuild失败记录

拿到node_modules后更换 执行npm rebuild 重新构建 报错 node版本不一致 nvm切换 版本 不成功 换个窗口又变回原来版本号了 设置默认版本 nvm alias default 14.16.1 发现下面还有一个stable的还指向原来版本 nvm alias stable 14.16.1 rebuild 还是失败 逐个rebuild 每个依赖单…

视频转码方法:多种格式视频批量转FLV视频的技巧

随着互联网的发展&#xff0c;视频已成为日常生活中不可或缺的一部分。然而&#xff0c;不同的视频格式可能适用于不同的设备和平台&#xff0c;因此需要进行转码。在转码之前&#xff0c;要了解各种视频格式的特点和适用场景。常见的视频格式包括MP4、AVI、MKV、FLV等。其中&a…

Selenium安装WebDriver最新Chrome驱动(含116/117/118/119)

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

Labview中for循环“无法终止”问题?即使添加了条线接线端,达到终止条件后,仍在持续运行?

关键&#xff1a; 搞清楚“运行”和“连续运行”两种运行模式的区别。 出现题目中所述问题&#xff0c;大概率是因为代码运行在“连续运行“模式下。 可以通过添加 探针 的方式&#xff0c;加深理解&#xff01;

软件测试:测试分类

一. 按照测试对象划分 1.1 界面测试 界面测试(简称UI测试),按照界面的需求(UI设计稿)和界面的设计规则,对我们软件界面所展示的全部内容进行测试和检查,一般包括如下内容: • 验证界面内容的完整性,一致性,准确性,友好性,兼容性.比如页面内容对屏幕大小的自适应,换行,内容是否…

面向开发者的Android

Developerhttps://developer.android.google.cn/?hlzh-cn SDK 平台工具版本说明https://developer.android.google.cn/studio/releases/platform-tools?hlzh-cn#revisions Android SDK Platform-Tools 是 Android SDK 的一个组件。它包含与 Android 平台进行交互的工具…

SpringBoot——日志及原理

优质博文&#xff1a;IT-BLOG-CN 一、SpringBoot日志 选用 SLF4j&#xff08;接口&#xff09;和 logback&#xff08;实现类&#xff09;&#xff0c;除了上述日志框架&#xff0c;市场上还存在 JUL(java.util.logging)、JCL(Apache Commons Logging)、Log4j、Log4j2、SLF4j…

ES6中实现继承

本篇文章主要说明在ES6中如何实现继承&#xff0c;学过java的小伙伴&#xff0c;对class这个关键字应该不陌生&#xff0c;ES6中也提供了class这个关键字作为实现类的语法糖&#xff0c;咱们一起实现下ES6中的继承。 实现思路 首先直接通过class来声明一个Teacther类&#xff…

毕业设计ASP.NET 2368酒店信息管理系统【程序源码+文档+调试运行】

一、摘要 本文旨在设计并实现一个功能全面、易于使用的酒店信息管理系统。系统将管理员、客户和前台客服三种用户的需求纳入考虑&#xff0c;并针对每种用户设计了相应的功能模块。系统功能包括用户管理、客户管理、客房管理、商品管理、客房预订管理、入住管理和系统管理。此…

【图数据库实战】HugeGraph图计算流程

HugeGraph是一款易用、高效、通用的开源图数据库系统&#xff08;Graph Database&#xff0c;GitHub项目地址&#xff09;&#xff0c; 实现了Apache TinkerPop3框架及完全兼容Gremlin查询语言&#xff0c; 具备完善的工具链组件&#xff0c;助力用户轻松构建基于图数据库之上的…

聊一聊go的单元测试(goconvey、gomonkey、gomock)

文章目录 概要一、测试框架1.1、testing1.2、stretchr/testify1.3、smartystreets/goconvey1.4、cweill/gotests 二、打桩和mock2.1、打桩2.2、mock2.2.1、mockgen2.2.1、示例 三、基准测试和模糊测试3.1、基准测试3.2、模糊测试 四、总结4.1、小结4.2、其他4.3、参考资料 概要…