Synchronized方法锁、对象锁、类锁区别

synchronized,这个东西我们一般称之为”同步锁“,他在修饰代码块的时候需要传入一个引用对象作为“锁”的对象。

  1. 在修饰方法的时候,默认是当前对象作为锁的对象
  2. 在修饰类时,默认是当前类的Class对象作为所的对象
    故存在着方法锁、对象锁、类锁 这样的概念
    那么我们来大致看一下这三种锁

一、方法锁(synchronized修饰方法时)(其实也可以算是对象锁)

通过在方法声明中加入synchronized关键字来声明synchronized方法。
synchronized 方法锁控制对类成员变量的访问:
每个类实例对应一把锁
每个synchronized方法都必须获得调用该方法的类实例的”锁“方能执行,否则所属线程阻塞。

方法一旦执行,就会独占该锁,一直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,从而重新进入可执行状态。

这种机制确保了同一时刻对于每一个类的实例,其所有声明为synchronized的成员函数中之多只有一个处于可执行状态,从而有效避免了类成员变量的访问冲突。

ok,下方介绍一个火车站卖票的例子,一共1000张票,有4个窗口卖票,卖票的方法被我定义为同步的,即每个卖票过程会卖出4张票,卖完之后才允许其他窗口卖票

大家看看代码,体会一下

public class LockTest {static int tickets = 1000;public synchronized void sellTickets(){int i=4;while (i>0){i--;tickets--;System.out.println(Thread.currentThread().getName()+":"+tickets);}}public static void main(String[] args) {LockTest lockTest = new LockTest();Thread thread1 = new Thread(new Runnable() {@Overridepublic void run() {lockTest.sellTickets();}});Thread thread2 = new Thread(new Runnable() {@Overridepublic void run() {lockTest.sellTickets();}});Thread thread3 = new Thread(new Runnable() {@Overridepublic void run() {lockTest.sellTickets();}});Thread thread4 = new Thread(new Runnable() {@Overridepublic void run() {lockTest.sellTickets();}});thread1.start();thread2.start();thread3.start();thread4.start();}
}

运行结果如下:

运行结果多运行几次会发现虽然线程的先后顺序会变化,但是每一个线程必定先卖出4张票之后才会去接着卖剩余的票。

下边我们来看下对象锁,其实方法锁 这个就属于对象锁

二、对象锁(synchronized修饰方法或代码块)

当一个对象中有synchronized method 或synchronized block 的时候,调用此对象的同步方法或进入其同步区域时,就必须先获得对象锁。

如果此对象的对象锁已被其他调用者占用,则需要等待此锁被释放。(方法锁也是对象锁)

java的所有对象都含有一个互斥锁,这个锁由jvm自动获取和释放。

线程进入synchronized 方法的时候获取该对象的锁,当然如果已经有线程获取了这个对象的锁,那么当前线程会等待;

synchronized方法正常返回或者抛异常而终止,jvm会自动释放对象锁。这里也体现了用synchronized来加锁的一个好处,即 :

方法抛异常的时候,锁仍然可以由jvm来自动释放
对象锁的两种方式

1、方法锁,上面已提及。

2、代码块形式

public void sellTickets(){int i=4;synchronized(this) {while (i > 0) {i--;tickets--;System.out.println(Thread.currentThread().getName() + ":" + tickets);}}}

执行效果一样。

三、类锁(synchronized修饰静态的方法或者代码块)

由于一个class不论被实例化多少次,其中的静态方法和静态变量在内存中都只有一份。所以,一旦一个静态的方法被声明为synchronized。此类所有的实例对象在调用此方法,共用同一把锁,我们称之为类锁。
对象锁是用来控制实例方法之间的同步,而类锁是用来控制静态方法(或者静态变量互斥体)之间的同步的。
类锁只是一个概念上的东西,并不是真实存在的,他只是用来帮助我们理解锁定实例方法和静态方法的区别的。
java类可能会有很多对象,但是只有一个Class(字节码)对象,也就是说类的不同实例之间共享该类的Class对象。Class对象其实也仅仅是1个java对象,只不过有点特殊而已。
由于每个java对象都有1个互斥锁,而类的静态方法是需要Class对象。所以所谓的类锁,只不过是Class对象的锁而已。
获取类的Class对象的方法有好几种,最简单的是[类名.class]的方式。(百度:获取字节码的三种方式)

来看下类锁的两种方式
方式1:

public void sellTickets(){int i=4;synchronized(LockTest.class) {while (i > 0) {i--;tickets--;System.out.println(Thread.currentThread().getName() + ":" + tickets);}}}

方式2:

public static synchronized void sellTickets(){int i=4;while (i > 0) {i--;tickets--;System.out.println(Thread.currentThread().getName() + ":" + tickets);}}

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

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

相关文章

express+mysql+vue,从零搭建一个商城管理系统10--添加商品

提示:学习express,搭建管理系统 文章目录 前言一、新建models/goods.js二、新建routes/goods.js三、添加goods表四、添加商品总结 前言 需求:主要学习express,所以先写service部分 一、新建models/goods.js models/goods.js con…

跨境电商独立站|代购+集运,这是什么东西?

代购集运,这是什么东西? 跨境集运搭建跨境电商独立站 代购,释义为代理购买。通俗意思就是找人帮忙购买你需要的商品,原因可以是你在当地买不到这件商品,可以是当地这件商品的价格比其他地区的贵,也可以是为…

模拟算法题练习(一)(扫雷,灌溉,回文日期)

目录 模拟算法介绍: (一、扫雷) (二、灌溉) (三、回文日期) 有一说一这题大佬的题解是真的强 模拟算法介绍: 模拟算法通过模拟实际情况来解决问题,一般容易理解但是实…

Windows上构建一个和Linux类似的Terminal

感谢大佬批评指正,现已更新 preview Target:致力打造最赏心悦目Window下的终端,同时能够很接近Linux的使用习惯 key word:windows终端美化 windows terminal windows powershell 类似Linux下的Window终端 Window也能用ll windows…

Linux编程3.1 进程-进程的概念

前情提及: 程序和进程内核中的进程结构C程序启动过程进程终止方式非局部跳转进程资源限制进程创建、执行和终止进程类型进程状态进程组 进程的概念 进程:程序运行,由操作系统内核对该程序进行资源的分配 , 进程中,再…

牛客练习赛122

D:圆 正着求删除的最小代价不好做,采用逆向思维,求选择一些不相交的线段使得构成一个圆的代价尽量大,最后答案就是所有线段权值之和减去最大代价。 那么如何求这个最大代价呢?显然区间DP 老套路:破环成链&#xff0…

【学习心得】网站运行时间轴(爬虫逆向)

一、网站运行时间轴 掌握网站运行时间轴,有助于我们对“请求参数加密”和“响应数据加密”这两种反爬手段的深入理解。 二、从网站运行的时间轴角度来理解两种反爬手段 1、加载HTML: 这是浏览器访问网站时的第一步,服务器会返回基础…

2024|CISP认证详细报考流程和条件

证书介绍 CISP(Certified Information Security Professional,注册信息安全专业人员)证书是由中国信息安全测评中心(CNITSEC)颁发的专业资质证书,旨在为信息安全领域培养和认证具备一定专业水平的安全人才…

5.测试教程 - 进阶篇

文章目录 1.按测试对像划分1.1**界面测试**1.2**可靠性测试**1.3**容错性测试**1.4**文档测试**1.5**兼容性测试**1.6**易用性测试**1.7**安装卸载测试**1.8**安全测试**1.9**性能测试**1.10**内存泄漏测试** 2.按是否查看代码划分2.1黑盒测试(Black-box Testing)2.2白盒测试(W…

框架漏洞-->Struts2 Docker_Vulnhub搭建

来浅浅的讲一下Struts2漏洞 目录 1.Docker_Vulnhub搭建 2.Struts2 3.Struts2的框架特征 4.S2-029-->Remote Code Execution 5.漏洞复现 1.RCE 2.Getshell 1.Docker_Vulnhub搭建 因为我用的是Linux,所以我选择直接搭个docker,这里我建议先换个…

绝对定位的一些特性;CSS绝对定位absolute

想要实现如下效果: yellow区域是宽度是100%;想要一个按钮在右侧,且和蓝色区域右侧对齐 思考 毋庸置疑,按钮肯定得使用绝对定位,但是绝对定位的定位位置肯定不能写死,因为这个是个公共组件,黄色…

WPF TabControl 滚动选项卡

文章目录 前言相关链接TabControl是什么东西通过模板副本查看样式IsItemsHost如何修改HandyControl的TabControl 滚动 总结 前言 我原本以为是很简单的事情,但是没想到实际做起来还是有很多的基础知识点的。 相关链接 WPF 控件库——可拖动选项卡的TabControl Tab…