【并发编程】Synchronized的使用

news2024/9/20 1:22:57

📫作者简介:小明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的对象实例(锁是括号里面的对象),对给定对象加锁,进入同步代码库前要获得给定对象的锁

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

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

相关文章

华东理工李洪林课题组开发 Macformer,加速大环类药物发现

大环类化合物是指由 12 个以上原子组成的小分子或肽。相较于其他小分子化合物&#xff0c;大环类化合物在结构和性能上有着诸多优势&#xff0c;也因此被视为各类靶点的潜在治疗药物。 基于药物化学合成的大环类似物是大环类药物的一个主要来源。然而&#xff0c;由于合成方法…

力扣刷题-二叉树-完全二叉树的节点个数

222.完全二叉树的节点个数 给出一个完全二叉树&#xff0c;求出该树的节点个数。 示例 1&#xff1a; 输入&#xff1a;root [1,2,3,4,5,6] 输出&#xff1a;6 示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;0 示例 3&#xff1a; 输入&#xff1a;root [1]…

拼图游游戏代码

一.创建新项目 二.插入图片 三.游戏的主界面 1.代码 package com.itheima.ui;import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.Random;import javax.swing…

【Spring进阶系列丨第三篇】Spring核心技术之 IoC 与 DI 实战案例

前言 在上一篇文章中&#xff0c;我们学习了IoC与DI的相关概念与原理&#xff0c;现在让我们 以HelloWorld为例&#xff0c;编写一个程序&#xff0c;让创建对象的工作由Spring帮助我们创建。 一同感受一下Spring框架带给我们开发的便捷性。 文章目录 前言一、编写Java类二、传…

IDEA调用接口超时,但Postman可成功调用接口

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

基于非洲秃鹫算法优化概率神经网络PNN的分类预测 - 附代码

基于非洲秃鹫算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于非洲秃鹫算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于非洲秃鹫优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

消息中间的应用场景

1、异步处理 比如用户在电商网站下单&#xff0c;下单完成后会给用户推送短信或邮件&#xff0c;发短信和邮件的过程就可以异步完成。因为下单付款是核心业务&#xff0c;发邮件和短信并不属于核心功能&#xff0c;并且可能耗时较长&#xff0c;所以针对这种业务场景可以选择先…

趣学python编程(六、关于蓝桥杯比赛)

蓝桥杯全国软件和信息技术专业人才大赛简称“蓝桥杯”&#xff0c;是由工业和信息化部人才交流中心举办的国内最大的信息技术竞赛。为促进中小学科技创新&#xff0c;提升中小学生逻辑思维&#xff0c;发现和培养面向未来的科技精英人才。 蓝桥杯介绍 蓝桥杯全国软件和信息技术…

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

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

贪吃蛇代码

一.准备 1.新建项目 2.放进照片 3.创建两个包放置图片类和入口类 二&#xff0c;游戏界面 package com.snake.view;import java.awt.Color; import java.awt.EventQueue; import java.awt.Font; import java.awt.Frame; import java.awt.Graphics; import java.awt.Image; i…

前缀和(c++,超详细,含二维)

前缀和与差分 当给定一段整数序列a1,a2,a3,a4,a5…an; 每次让我们求一段区间的和&#xff0c;正常做法是for循环遍历区间起始点到结束点&#xff0c;进行求和计算&#xff0c;但是当询问次数很多并且区间很长的时候 比如&#xff0c;10^5 个询问和10^6区间长度&#xff0c;相…

[JDK工具-2] javap 类文件解析工具-帮助理解class文件,了解Java编译器机制

文章目录 1. javap -version 版本信息2. javap -verbose 输出附加信息3. javap -l 显示行号和局部变量列表4. javap -c 对代码进行反汇编&#xff08;或叫反编译生成汇编代码&#xff0c;一般说反编译是生成java代码&#xff09;&#xff0c;分解方法代码&#xff0c;也就是显示…

电机应用开发-PID控制器参数整定

PID控制器参数整定 比例调节&#xff1a;调节作用快&#xff0c;系统一出现偏差&#xff0c;调节器立即将偏差放大输出。 积分调节&#xff1a;输出变化和输入偏差的积分成正比。输出不仅取决于偏差大小&#xff0c;还取决于偏差存在的时间。只要有偏差存在&#xff0c;尽管偏差…

【23真题】超难985!做完感觉没学过!

本套试卷难度分析&#xff1a;22年西北工业大学827考研真题&#xff0c;我也发布过&#xff0c;若有需要&#xff0c;戳这里自取&#xff01;本套试题内容有难度&#xff0c;题目考察全为大题&#xff0c;题目不多&#xff01;但是题目都很新颖&#xff0c;状态方程的题目考察较…

MySQL为什么选择了B+树

首先MySQL的数据**&#xff08;索引记录&#xff09;**是存在磁盘里的&#xff0c;磁盘读取非常慢&#xff0c;所以要尽可能减少磁盘操作&#xff0c;因此我们需要更好的利用索引。 首先索引按顺序排列了数据&#xff0c;那么很显然最好的查找方式是二分查找&#xff0c;数组自…

解决证书加密问题:OpenSSL与urllib3的兼容性与优化

在使用客户端证书进行加密通信时&#xff0c;用户可能会遇到一些问题。特别是当客户端证书被加密并需要密码保护时&#xff0c;OpenSSL会要求用户输入密码。这对于包含多个调用的大型会话来说并不方便&#xff0c;因为密码无法在连接的多个调用之间进行缓存和重复使用。用户希望…

改进YOLOv8:结合ConvNeXt V2骨干网络!使用MAE共同设计和扩展ConvNet

🗝️YOLOv8实战宝典--星级指南:从入门到精通,您不可错过的技巧   -- 聚焦于YOLO的 最新版本, 对颈部网络改进、添加局部注意力、增加检测头部,实测涨点 💡 深入浅出YOLOv8:我的专业笔记与技术总结   -- YOLOv8轻松上手, 适用技术小白,文章代码齐全,仅需 …

java桌面程序

目标之一是把打印导出的功能最终用java实现一套&#xff0c;首先选定javafx&#xff0c;因为idea默认创建工程就带的javafx&#xff0c;没找到swing。 创建工程&#xff0c;这里要选1.8&#xff0c;高版本jdk默认不带fx 实现主界面的代码 package sample;import javafx.app…

【DevOps】Git 图文详解(五):远程仓库

Git 图文详解&#xff08;五&#xff09;&#xff1a;远程仓库 1.远程用户登录1.1 &#x1f511; 远程用户登录&#xff1a;HTTS1.2 &#x1f511; 远程用户登录&#xff1a;SSH 2.远程仓库指令 &#x1f525;3.推送 push / 拉取 pull4.fetch 与 pull 有什么不同 &#xff1f; …