个人对java中对象锁与类锁的一些理解与实例
一 什么是对象锁
对象锁也叫方法锁,是针对一个对象实例的,它只在该对象的某个内存位置声明一个标识该对象是否拥有锁,所有它只会锁住当前的对象,而并不会对其他对象实例的锁产生任何影响,不同对象访问同一个被synchronized修饰的方法的时候不会阻塞,
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public class MyObject { private synchronized void method1(){ try { System.out.println(Thread.currentThread().getName()); Thread.sleep( 4000 ); } catch (InterruptedException e) { e.printStackTrace(); } } //synchronized修饰为同步方法,如果先调用method1,则4秒后才会调用method2 //如果不用synchronized修饰,则可以直接异步调用,没有影响 private void method2(){ System.out.println(Thread.currentThread().getName()); } } |
创建一个类,synchronized修饰普通方法,即为对象锁,那么这个时候,多个线程访问同一个对象实例的这个方法时,是会同步的,并且只有一个线程执行完,另一个线程才会执行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public static void main(String[] args) { //创建一个对象 MyObject myObject= new MyObject(); Thread t1= new Thread ( new Runnable() { @Override public void run() { myObject.method1(); } }, "t1" ); Thread t2= new Thread ( new Runnable() { @Override public void run() { myObject.method1(); } }, "t2" ); t1.start(); t2.start(); } |
即,打印t14秒之后,t2才会打印,因为两个线程调用的是同一个对象实例的方法,即同一把锁,所有会同步执行
而如果是不同对象实例的话,则没有影响,因为两个线程调用的是不同实例的锁方法,即不是同一把锁,没有关系,所以会正常输出,不会同步
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public static void main(String[] args) { //创建两个对象 MyObject myObject= new MyObject(); MyObject myObject01= new MyObject(); Thread t1= new Thread ( new Runnable() { @Override public void run() { myObject.method1(); } }, "t1" ); Thread t2= new Thread ( new Runnable() { @Override public void run() { myObject01.method1(); } }, "t2" ); t1.start(); t2.start(); } |
二 对象锁的几种形式以及应用案例
1 synchronized修饰普通方法属于对象锁,
2,
synchronized修饰的代码块传入this也属于对象锁
应用:减小锁粒度,第二种形式就比较好,比如A线程调用一个同步方法需要很长时间,那么B就要等待很长时间,这个时候可以将必须同步的代码使用synchronized代码块,
不不需要同步的先执行,节约资源
三 类锁
类锁是锁住整个类,当有多个线程来声明这个类的对象时候将会被阻塞,直到拥有这个类锁的对象呗销毁或者主动释放了类锁,这个时候在被阻塞的线程被挑选出一个占有该类锁,声明该类的对象。其他线程继续被阻塞住
(上面百度的),即一句话,不管多少个对象,多少个对象,共用一把多,且只有一把,不管怎么调用,都会同步
上面方法加static变类锁:
1 2 3 4 5 6 7 8 | private static synchronized void method1(){ try { System.out.println(Thread.currentThread().getName()); Thread.sleep( 4000 ); } catch (InterruptedException e) { e.printStackTrace(); } } |
这个时候无论线程调用的是多少个对象实例的方法,都会同步
四 类锁形式
1 synchronized修饰静态方法属于类锁
2
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异