对象锁与类锁

不同锁互不影响,共用一个锁,可能会发生阻塞。

1.在修饰静态方法时,锁定的是当前类的 Class 对象,在下面的例子中就是SycTest1.class

 2.当修饰非静态方法时,锁定的就是 this 对象,即当前的实例化对象

public class SyncTest1 {// synchronized修饰非静态方法public synchronized void test1() {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + " : " + i);try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}// synchronized修饰this对象,即当前的实例化对象public void test2() {synchronized (this) {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + " : " + i);try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}}public static void main(String[] args) {SyncTest1 t1 = new SyncTest1();new Thread(new Runnable() {@Overridepublic void run() {t1.test1();}}, "thread1").start();new Thread(new Runnable() {@Overridepublic void run() {t1.test2();}}, "thread2").start();}
}
thread1 : 0
thread1 : 1
thread1 : 2
thread1 : 3
thread1 : 4
thread2 : 0
thread2 : 1
thread2 : 2
thread2 : 3
thread2 : 4

通过上面代码中可以看到,在test1里修饰的是非静态方法,即锁定的为当前实例化对象,即对象锁,test2锁定的就是this对象,也是对象锁,也就是thread1和thread2请求的是同一把锁,所以是Thread1运行完之后Thread2才运行。 

public class SyncTest1 {// 修饰静态方法public static synchronized void test1() {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + " : " + i);try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}// 修饰类对象public void test2() {synchronized (SyncTest1.class) {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + " : " + i);try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}}public static void main(String[] args) {SyncTest1 t1 = new SyncTest1();new Thread(new Runnable() {@Overridepublic void run() {SyncTest1.test1();}}, "thread1").start();new Thread(new Runnable() {@Overridepublic void run() {t1.test2();}}, "thread2").start();}
}
thread1 : 0
thread1 : 1
thread1 : 2
thread1 : 3
thread1 : 4
thread2 : 0
thread2 : 1
thread2 : 2
thread2 : 3
thread2 : 4

通过上面代码中可以看到,在test1里修饰的是静态方法,即锁定的为当前的类对象,即类锁,而test2锁定的SyncTest1.class,也是类锁,也就是thread1和thread2请求的是同一把锁,所以是Thread1运行完之后Thread2才运行。  

public class SyncTest1 {// 修饰静态方法public static synchronized void test1() {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + " : " + i);try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}// 修饰非静态方法public synchronized void test2() {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + " : " + i);try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) {SyncTest1 t1 = new SyncTest1();new Thread(new Runnable() {@Overridepublic void run() {SyncTest1.test1();}}, "thread1").start();new Thread(new Runnable() {@Overridepublic void run() {t1.test2();}}, "thread2").start();}
}
thread1 : 0
thread2 : 0
thread1 : 1
thread2 : 1
thread2 : 2
thread1 : 2
thread2 : 3
thread1 : 3
thread2 : 4
thread1 : 4

通过上面代码中可以看到,在test1里修饰的是静态方法,即锁定的为当前的类对象,即类锁,而test2锁定的非静态方法,也就是对象锁,也就是thread1和thread2请求的不是同一把锁,所以他们是两个锁,互不影响。

对象锁与类锁的区别:

对象锁和类锁其实本质上都是一种锁,区别在于一个类可以有多个对象锁,但类锁只有一个。 故使用 synchronized 对类加锁是唯一的,当一个线程拿到类锁,其他线程在执行到任何需要类锁的方法时都将阻塞。 总体来说类锁具有唯一性。

类的实例化对象可以有多个,对每个实例化对象加锁是互不干扰的,它们不具备全局唯一性,这里我们称它为对象锁。
对象锁一般可以用于细粒度锁的创建。

借鉴:Java并发编程-类锁与对象锁剖析 - 掘金 

synchronized的对象锁和类锁的区别 - 掘金

近日总结:感冒了......emo......


 

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

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

相关文章

【Git教程】(四)版本库 —— 存储系统,存储目录,提交对象及其命名、移动与复制~

Git教程 版本库 1️⃣ 一种简单而高效的存储系统2️⃣ 存储目录&#xff1a;Blob 与 Tree3️⃣ 相同数据只存储一次4️⃣ 压缩相似内容5️⃣ 不同文件的散列值相同6️⃣ 提交对象7️⃣ 提交历史中的对象重用8️⃣ 重命名、移动与复制&#x1f33e; 总结 事实上&#xff0c;我们…

keil MDK安装armcc V5编译器

不知道从什么时候开始&#xff0c;Keil MDK默认不支持V5的编译器了&#xff0c;里面默认只有V6的编译器&#xff0c;设置界面跟V5有很大的差异不太熟悉。最可怕的是&#xff0c;之前使用V5编译的工程&#xff0c;换成V6编译器后居然报错...虽然修改一下应该也可以正常编译&…

SQL面试题(2)

第一题 创建trade_orders表: create table `trade_orders`( `trade_id` varchar(255) NULL DEFAULT NULL, `uers_id` varchar(255), `trade_fee` int(20), `product_id` varchar(255), `time` varchar(255) )ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_…

web自动化笔记九:验证码的处理方式

一、验证码常用的处理方式 ①、说明&#xff1a;Selenium中并没有对验证码处理的方法&#xff0c;在这里我们介绍一下针对验证码的几种常用处理方式 ②、方式&#xff1a; 1&#xff09;、去掉验证码&#xff08;测试环境下采用&#xff09; …

RDD算子介绍

1. RDD算子 RDD算子也叫RDD方法&#xff0c;主要分为两大类&#xff1a;转换和行动。转换&#xff0c;即一个RDD转换为另一个RDD&#xff0c;是功能的转换与补充&#xff0c;比如map&#xff0c;flatMap。行动&#xff0c;则是触发任务的执行&#xff0c;比如collect。所谓算子…

Mac专用投屏工具AirServer 7.27 for Mac中文版2024最新图文教程

Mac专用投屏工具AirServer 7.27 for Mac中文版是一款适用于Mac的投屏工具&#xff0c;可以将Mac屏幕快速投影到其他设备上&#xff0c;如电视、投影仪、平板等。 Mac专用投屏工具AirServer 7.27 for Mac中文版具有优秀的兼容性&#xff0c;可以与各种设备配合使用。无论是iPhon…

基于springboot+vue的在线考试系统(源码+论文)

文章目录 目录 文章目录 前言 一、功能设计 二、功能页面 三、论文 前言 现在我国关于在线考试系统的发展以及专注于对无纸化考试的完善程度普遍不高&#xff0c;关于对考试的模式还大部分还停留在纸介质使用的基础上&#xff0c;这种教学模式已不能解决现在的时代所产生的考试…

【MySQL】数据库的操作

【MySQL】数据库的操作 目录 【MySQL】数据库的操作创建数据库数据库的编码集和校验集查看系统默认字符集以及校验规则查看数据库支持的字符集查看数据库支持的字符集校验规则校验规则对数据库的影响数据库的删除 数据库的备份和恢复备份还原不备份整个数据库&#xff0c;而是备…

YOLOv9改进|增加SPD-Conv无卷积步长或池化:用于低分辨率图像和小物体的新 CNN 模块

专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;主力高效涨点&#xff01;&#xff01;&#xff01; 一、文章摘要 卷积神经网络(CNNs)在计算即使觉任务中如图像分类和目标检测等取得了显著的成功。然而&#xff0c;当图像分辨率较低或物体较小时&…

【LeetCode刷题】146. LRU 缓存

请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中&#xff0c;则返回关键字的值&#xff0c;否则返回 -…

【InternLM 实战营笔记】浦语·灵笔的图文理解及创作部署、 Lagent 工具调用 Demo

浦语灵笔的图文理解及创作部署 浦语灵笔是基于书生浦语大语言模型研发的视觉-语言大模型&#xff0c;提供出色的图文理解和创作能力&#xff0c;结合了视觉和语言的先进技术&#xff0c;能够实现图像到文本、文本到图像的双向转换。使用浦语灵笔大模型可以轻松的创作一篇图文推…

进程间的通信 -- 共享内存

一 共享内存的概念 1. 1 共享内存的原理 之前我们学过管道通信&#xff0c;分为匿名管道和命名管道&#xff0c;匿名管道通过父子进程的属性继承原理来完成父子进程看到同一份资源的目的&#xff0c;而命名管道则是通过路径与文件名来唯一标识管道文件&#xff0c;来让不同的进…

typescript 的常用方式

文章目录 前言一、绑定props 默认值的方式&#xff1a;withDefaults1.vue2 的props设置默认值2.vue3 的props设置默认值(1) 不设置默认值的写法(2) 设置默认值的写法&#xff08;分离模式&#xff09;(3) 设置默认值的写法&#xff08;组合模式&#xff09; 二、定义一个二维数…

Matlab在同一张图中如何加入多个图例

根据代码最终画出的图片如下&#xff1a; 其实原理很简单&#xff0c;就是在一张figure中画多个坐标轴&#xff0c;每个坐标轴都有对应的图例&#xff0c;之后再将多余坐标轴隐藏&#xff0c;只保留一个即可。 代码如下&#xff1a; clear all; close all;dd_linewidth 1;a …

maven archetype 项目原型

拓展阅读 maven 包管理平台-01-maven 入门介绍 Maven、Gradle、Ant、Ivy、Bazel 和 SBT 的详细对比表格 maven 包管理平台-02-windows 安装配置 mac 安装配置 maven 包管理平台-03-maven project maven 项目的创建入门 maven 包管理平台-04-maven archetype 项目原型 ma…

Spring学习笔记(六)利用Spring的jdbc实现学生管理系统的用户登录功能

一、案例分析 本案例要求学生在控制台输入用户名密码&#xff0c;如果用户账号密码正确则显示用户所属班级&#xff0c;如果登录失败则显示登录失败。 &#xff08;1&#xff09;为了存储学生信息&#xff0c;需要创建一个数据库。 &#xff08;2&#xff09;为了程序连接数…

php源码 单色bmp图片取模工具 按任意方式取模 生成字节数组 自由编辑点阵

http://2.wjsou.com/BMP/index.html 想试试chatGPT4生成&#xff0c;还是要手工改 php 写一个网页界面上可以选择一张bmp图片&#xff0c;界面上就显示这张bmp图片&#xff0c; 点生成取模按钮&#xff0c;在图片下方会显示这张bmp图片的取模数据。 取模规则是按界面设置的&a…

Linux 的交换空间(swap)是什么?有什么用?

目录 swap是什么&#xff1f;swap有什么用&#xff1f;swap使用典型场景如何查看你的系统是否用到交换空间呢&#xff1f;查看系统中swap in/out的情况 swap是什么&#xff1f; swap就是磁盘上的一块区域。它和Windows系统中的交换文件作用类似&#xff0c;但是它是一段连续的…

03、MongoDB -- MongoDB 权限的设计

目录 MongoDB 权限的设计演示前准备&#xff1a;启动 mongodb 服务器 和 客户端 &#xff1a;1、启动单机模式的 mongodb 服务器2、启动 mongodb 的客户端 MongoDB 权限的设计1、MongoDB 的每个数据库都可以保存用户&#xff0c;不止admin数据库可以保存用户。2、保存用户的数据…

Linux 学习笔记(8)

八、 启动引导 1 、 Linux 的启动流程 1) BIOS 自检 2) 启动 GRUB/LILO 3) 运行 Linux kernel 并检测硬件 4) 挂载根文件系统 5) 运行 Linux 系统的第一个进程 init( 其 PID 永远为 1 &#xff0c;是所有其它进程的父进程 ) 6) init 读取系统引导配置文件…