Synchronized的三种写法

2023-11-17

文章目录

  • 前言
  • 一、synchronized是什么
  • 二、synchronized的三种写法
    • 1、同步代码块
    • 2、在实例方法上使用synchronized
    • 3、在静态方法上使用synchronized
  • 总结





前言

总结一下自己在学习Synchronized 以及它的三种写法。

一、synchronized是什么?

synchronized是由JVM实现的一种互斥同步的一种方式,被synchronized修饰过的程序块在编译前后被编译器生成了monitorenter和monitorexit两个字节码指令。

如果这个方法使用了synchronized的时候,代表它加上了锁,运行此方法的时都要检查它有没有被其他线程正在使用(或者该类的其他同步方法),有的话要等它使用完,没有的话则直接锁定调用者,然后直接运行。它包括两种用法:synchronized方法和synchronized块。



二、synchronized的三种写法




1、同步代码块

代码如下(示例):

package com.demo;

public class Demo {
    public static void main(String[] args) throws InterruptedException {
        MyClass mc=new MyClass();
        
        Thread t1=new MyThread(mc);
        Thread t2=new MyThread(mc);
        
        t1.setName("t1");
        t2.setName("t2");
        
        t1.start();
        Thread.sleep(1000);//这个睡眠的作用 是为了保证t1线程先执行。
        t2.start();
    }

}

class MyThread extends Thread {
    private MyClass mc;
    
    public MyThread (MyClass mc) {
        this.mc = mc;
    }
    
    public void run(){
        if(Thread.currentThread().getName().equals("t1")) {
            mc.doSome();
        }
        if(Thread.currentThread().getName().equals("t2")) {
            mc.doOther();
        }
    }
    
}

class MyClass{
    //synchronized出现再类方法上,表示锁this。
    public synchronized void doSome(){
        System.out.println("doSome 执行开始");
        try {
            Thread .sleep(1000*5);//睡眠五秒
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("doSome 执行结束");
    }
    
    public void doOther() {
        System.out.println("doOther 执行开始");
        System.out.println("doOther 执行结束");
    }
}
doOther方法执行的时候不需要等待被修饰过的doSome方法结束,因为doOther方法没有被synchronized修饰,所以它不用排队等待。 

2、在实例方法上使用synchronized

代码如下(示例):

package com.demo;

public class Demo {
    public static void main(String[] args) throws InterruptedException {
        MyClass mc=new MyClass();
        
        Thread t1=new MyThread(mc);
        Thread t2=new MyThread(mc);
        
        t1.setName("t1");
        t2.setName("t2");
        
        t1.start();
        Thread.sleep(1000);//这个睡眠的作用 是为了保证t1线程先执行。
        t2.start();
    }

}

class MyThread extends Thread {
    private MyClass mc;
    
    public MyThread (MyClass mc) {
        this.mc = mc;
    }
    
    public void run(){
        if(Thread.currentThread().getName().equals("t1")) {
            mc.doSome();
        }
        if(Thread.currentThread().getName().equals("t2")) {
            mc.doOther();
        }
    }
    
}

class MyClass{
    //synchronized出现再类方法上,表示锁this。
    public synchronized void doSome(){
        System.out.println("doSome 执行开始");
        try {
            Thread .sleep(1000*5);//睡眠五秒
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("doSome 执行结束");
    }
    
    public synchronized void doOther() {
        System.out.println("doOther 执行开始");
        System.out.println("doOther 执行结束");
    }
}
在两个方法前都加上synchronized修饰,doOther方法执行的时候需要等待doSome方法结束完之后才执行doSome,因为锁被doSome占了,所以要排队等待。 
我们再开启一个线程:package com.demo;

public class Demo {
    public static void main(String[] args) throws InterruptedException {
        //开启两个线程
        MyClass mc1=new MyClass();
        MyClass mc2=new MyClass();
        
        Thread t1=new MyThread(mc1);
        Thread t2=new MyThread(mc2);
        
        t1.setName("t1");
        t2.setName("t2");
        
        t1.start();
        Thread.sleep(1000);//这个睡眠的作用 是为了保证t1线程先执行。
        t2.start();
    }

}

class MyThread extends Thread {
    private MyClass mc;
    
    public MyThread (MyClass mc) {
        this.mc = mc;
    }
    
    public void run(){
        if(Thread.currentThread().getName().equals("t1")) {
            mc.doSome();
        }
        if(Thread.currentThread().getName().equals("t2")) {
            mc.doOther();
        }
    }
    
}

class MyClass{
    //synchronized出现再类方法上,表示锁this。
    public synchronized void doSome(){
        System.out.println("doSome 执行开始");
        try {
            Thread .sleep(1000*5);//睡眠5秒
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("doSome 执行结束");
    }
    
    public synchronized void doOther() {
        System.out.println("doOther 执行开始");
        System.out.println("doOther 执行结束");
    }
}doOther方法执行的时候不需要等待doSome方法结束,因为MyClass对象是两个,两把锁,互不干涉。 

3、在静态方法上使用synchronized

package com.demo;


public class Demo {
    public static void main(String[] args) throws InterruptedException {
        //开启两个线程
        MyClass mc1=new MyClass();
        MyClass mc2=new MyClass();
        
        Thread t1=new MyThread(mc1);
        Thread t2=new MyThread(mc2);
        
        t1.setName("t1");
        t2.setName("t2");
        
        t1.start();
        Thread.sleep(1000);//这个睡眠的作用 是为了保证t1线程先执行。
        t2.start();
    }

}

class MyThread extends Thread {
    private MyClass mc;
    
    public MyThread (MyClass mc) {
        this.mc = mc;
    }
    
    public void run(){
        if(Thread.currentThread().getName().equals("t1")) {
            mc.doSome();
        }
        if(Thread.currentThread().getName().equals("t2")) {
            mc.doOther();
        }
    }
    
}

class MyClass{
    //synchronized出现再类方法上,表示锁this。
    public synchronized static void doSome(){
        System.out.println("doSome 执行开始");
        try {
            Thread .sleep(1000*5);//睡眠5秒
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("doSome 执行结束");
    }
    
    public synchronized static void doOther() {
        System.out.println("doOther 执行开始");
        System.out.println("doOther 执行结束");
    }
}

doOther方法执行的时候不需要等待doSome方法结束,因为静态方法是类锁,不管创建了几个对象,类锁只有一把。





总结

对象锁:1个对象1把锁,100个对象有100把锁。

类锁:100个对象,全部都是这一把锁。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Synchronized的三种写法 的相关文章

  • openpyxl 2.4.2:保存后公式生成的单元格值为空

    我使用 openpyxl 打开文件 编辑一些单元格并保存更改 这是一个例子 import openpyxl book openpyxl load workbook sheet path sheet book active for row i
  • 在 Django 中定义视图和 url。为什么调用函数时不使用括号?

    我已经在经历 Python速成课程 目前正在进行 Django Web应用程序项目 学习日志 阶段 有些东西与我已经学到的相矛盾 views py file from django shortcuts import render def i
  • 如何屏蔽 PyTorch 权重参数中的权重?

    我正在尝试在 PyTorch 中屏蔽 强制为零 特定权重值 我试图掩盖的权重是这样定义的def init class LSTM MASK nn Module def init self options inp dim super LSTM
  • 为什么我不能导入 geopandas?

    我唯一的代码行是 import geopandas 它给了我错误 OSError Could not find libspatialindex c library file 以前有人遇到过这个吗 我的脚本运行得很好 直到出现此错误 请注意
  • 如何使用pycaffe重构caffe网络

    我想要的是 加载网络后 我将分解一些特定的图层并保存新的网络 例如 原网 数据 gt conv1 gt conv2 gt fc1 gt fc2 gt softmax New net 数据 gt conv1 1 gt conv1 2 gt c
  • 使用 Django 的 post_save() 信号

    我有两张桌子 class Advertisement models Model created at models DateTimeField auto now add True author email models EmailField
  • 如何用 python 和 sympy 解决多元不等式?

    我对使用 python 和 Sympy 还很陌生 并且遇到了使用 sympy 解决多元不等式的问题 假设我的文件中有很多函数 如下所示 cst sqrt x 2 cst exp sqrt cst x 1 4 log log sqrt cst
  • Dask DataFrame 的逐行处理

    我需要处理一个大文件并更改一些值 我想做这样的事情 for index row in dataFrame iterrows foo doSomeStuffWith row lol doOtherStuffWith row dataFrame
  • 如何将条目中的部分文本加粗并更改其背景颜色?

    我正在创建一个基于 Tkinter 的 GUI 它有一个 Entry 小部件 我想将其文本的一部分加粗并更改其背景颜色 但我不知道我该怎么做 如果我使用文本小部件 我可以只使用标签 但看起来它们不能与条目小部件一起使用 此代码使用文本小部件
  • Sorted(key=lambda: ...) 背后的语法[重复]

    这个问题在这里已经有答案了 我不太明白背后的语法sorted 争论 key lambda variable variable 0 Isn t lambda随意的 为什么是variable在看起来像的内容中陈述了两次dict 我认为这里的所有
  • 使用 genfromtxt 导入 numpy 中缺失值的 csv 数据

    我有一个 csv 文件 看起来像这样 实际文件有更多的列和行 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 假设文件的名称是info csv如果我尝试使用导入它 data numpy genfromtxt i
  • 字典的嵌套列表

    我正在尝试创建dict通过嵌套list groups Group1 A B Group2 C D L y x 0 for y in x if y x 0 for x in groups d k v for d in L for k v in
  • 如何逐像素绘制正方形(Python,PIL)

    在空白画布上 我想使用 Pillow 逐像素绘制一个正方形 我尝试使用 img putpixel 30 60 155 155 55 绘制一个像素 但它没有执行任何操作 from PIL import Image def newImg img
  • 使用 Doc2vec 后如何解释 Clusters 结果?

    我正在使用 doc2vec 将关注者的前 100 条推文转换为矢量表示形式 例如 v1 v100 之后 我使用向量表示来进行 K 均值聚类 model Doc2Vec documents t size 100 alpha 035 windo
  • Plotly:如何避免巨大的 html 文件大小

    我有一个 3D 装箱模型 它使用绘图来绘制输出图 我注意到 绘制了 600 个项目 生成 html 文件需要很长时间 文件大小为 89M 这太疯狂了 我怀疑可能存在一些巨大的重复 或者是由单个项目的 add trace 方法引起的 阴谋 为
  • Scrapy 蜘蛛无法工作

    由于到目前为止没有任何效果 我开始了一个新项目 python scrapy ctl py startproject Nu 我完全按照教程操作 创建了文件夹和一个新的蜘蛛 from scrapy contrib spiders import
  • Pandas 在特定列将数据帧拆分为两个数据帧

    I have pandas我组成的 DataFrameconcat 一行由 96 个值组成 我想将 DataFrame 从值 72 中分离出来 这样 一行的前 72 个值存储在 Dataframe1 中 接下来的 24 个值存储在 Data
  • Google App Engine 中的自定义身份验证

    有谁知道或知道我可以在哪里学习如何使用 Python 和 Google App Engine 创建自定义身份验证流程 我不想使用 Google 帐户进行身份验证 并且希望能够创建自己的用户 如果不是专门针对 Google App Engin
  • 将此 MATLAB 代码转换为 Python 时我做错了什么?

    我正在努力将生成波形的 MATLAB 代码转换为 Python 就上下文而言 这是原子力显微镜带激发响应的模拟 与代码错误无关 在 MATLAB 中从 r vec 生成的图形与我在 Python 中生成的图形不同 我是否正确地将 MATLA
  • 如何识别图形线条

    我有以下格式的路径的 x y 数据 示例仅用于说明 seq p1 p2 0 20 2 3 1 20 2 4 2 20 4 4 3 22 5 5 4 22 5 6 5 23 6 2 6 23 6 3 7 23 6 4 每条路径都有多个点 它们

随机推荐

  • IDEA:Warning: No artifacts configured FIX

    问题 办法 Warning No artifacts configured 警告 未配置项目 给idea项目添加tomcat的时候出现 解决办法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 现在还不够 16 17
  • QT连接SQLserver详细教程

    Qt 连接 SQL Sever数据库 环境 一 配置 ODBC数据源 一 在SQL Sever Manger中添加 新的用户 1 打开如下自带的 MSS Management Studio 2 登录时选择 Windows 身份验证 3 去往
  • 在python中使用python-docx实现word文档自动化

    五一马上就要结束了 趁着今天休息的一天 给大家说说在python对办公文档处理 文章中说要详细的介绍python中几个对文档处理的库 今天就介绍一下word文档处理的python docx库 好了废话不多说开始吧 哈哈哈哈哈哈哈啊哈哈 py
  • 学习MongoDB 三: MongoDB无法启动的解决方法

    一简介 我们之前介绍了MongoDB入门 安装与配置 我们今天在打开MongDB时 我们先运行cmd exe进入dos命令界面 然后进入cd D mongodb bin目录下 启动服务或者mongo命令都报了错误 二 解决 1 net st
  • vue实现三级联动

    div div
  • 图片在盒子内等比展示不变形

    通过这个属性 object fit cover 使用场景如下 fatherBox 父盒子要有宽高 width 240px height 240px sonBox 子盒子 width 100 height 100 object fit cov
  • 7种Git错误以及解决方法

    使用Git的时候如果出现报错 要会解决Git错误 以下整理了七种Git错误以及解决的方法 1 当出现fatal not a git repository or any of the parent directories git时 说明不是一
  • vector find() 用法

    int main vector
  • STM32的PA0输出高电平的具体库函数代码操作

    在STM32中 可以使用库函数控制PA0输出高电平 具体的代码如下 初始化GPIOA的引脚模式 设置PA0为输出模式 GPIO InitTypeDef GPIO InitStruct HAL RCC GPIOA CLK ENABLE GPI
  • Score SDE 三种随机微分方程代码解读

    定义SDE类 定义了7个子函数 T End time of the SDE sde marginal prob Parameters to determine the marginal distribution of the SDE p t
  • 计算机二级-简单应用题

    题目要求 编写代码 以实现如下功能 键盘输入小明学习的课程名称及考分等信息 信息间采用空格分隔 每个课程一行 空行回车结束录入 示例格式如下 数学 90 语文 95 英语 86 物理 84 生物 87 屏幕输出得分最高的课程及成绩 得分最低
  • 去除指定css属性

    使得指定css样式失效 layui btn background image initial important 优先使用 layui btn background image initial important padding 0 10p
  • 像程序员一样思考_如何像程序员一样思考-解决问题的经验教训

    像程序员一样思考 by Richard Reis 理查德 里斯 Richard Reis 如何像程序员一样思考 解决问题的经验教训 How to think like a programmer lessons in problem solv
  • Vue-router2.0基础,秒会。

    如果不是模块式开发 请先引入 1 0基础 div h1 Hello App h1 p p div
  • Docker打开远程API服务

    一 开发环境 1 系统环境 2 docker版本 二 步骤 1 查看docker配置文件路径 2 编辑配置文件 3 重启docker 三 测试 1 查看docker客户端服务端版本 docker H localhost 2375 versi
  • C++ 在一个程序中调用exe

    生成exe的代码 include
  • StarRocks 运维工具 StarGo

    优质资源分享 学习路线指引 点击解锁 知识定位 人群定位 Python实战微信订餐小程序 进阶级 本课程是python flask 微信小程序的完美结合 从项目搭建到腾讯云部署上线 打造一个全栈订餐系统 Python量化交易实战 入门级 手
  • Spring Boot Admin 监控告警

    Spring Boot Admin 监控告警 要进行监控 需要两个Project 一个是Admin Server端 负责监控Spring boot的项目 另一个是Admin Client端 是被监控的Spring boot服务 当然也可以一
  • Android优化

    一 布局优化 布局优化就是删除布局中无用的控件和层级 可以用Hierarchy Viewer工具来检测 其次有选择地使用性能较低的ViewGroup include标签 include标签只支持以android layout开头的属性 比如
  • Synchronized的三种写法

    文章目录 前言 一 synchronized是什么 二 synchronized的三种写法 1 同步代码块 2 在实例方法上使用synchronized 3 在静态方法上使用synchronized 总结 前言 总结一下自己在学习Synch