栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java中对对象加锁的方法和对类加锁的方法会不会互相阻塞?

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java中对对象加锁的方法和对类加锁的方法会不会互相阻塞?

Java中对对象加锁的方法和对类加锁的方法会不会互相阻塞?

今天面试遇到这么一个问题:对对象加锁的方法和对类加锁的方法会不会互相阻塞?

然后我参照了网上的一些博客内容,写了以下程序验证:

他们的结果是交错输出的,也就是说他们是不阻塞的。

那么为什么会成为这样子呢?

先说一个Synchronized的原理

Synchronized关键字在编译的时候,会在同步块前后形成一个monitorenter和monitorexit的字节码指令,这两个字节码都需要一个reference类型的参数来指明要加锁和解锁的对象,在执行moniterenter指令的时候,首先要先获取加锁的对象,如果这个对象没有被锁定,就会把对象头里边锁的计数器加1,执行monitroexit的时候就会把锁的对象减一。

在执行synchronized (Solution.class)进入代码块的时候,他是对Solution的Class对象加锁,Class对象是每次加载Class文件在JVM中生成的对象,每个类对应着一个Class对象,这个Class对象是实际存在的,因此在进入synchronized (Solution.class)同步代码块的时候,会将对象头中锁的计数器加一。对实例对象synchronized (this)进行加锁的时候,则会在实例对象的对象头的计数器里边加一。因此他们是不通的加锁对象,因此不会阻塞。

那么对使用不同加载器加载的类加锁会不会阻塞呢?

我正在验证,之后补上。

结果和程序如下

public class Solution3 {
	
	static void run1() throws InterruptedException {
		synchronized (Solution.class) {
			for(int i=0;i<10;i++) {
				Thread.sleep(10);
				System.out.println(Thread.currentThread().getName());
			}
		}
	}
	void run2() throws InterruptedException {
		
		synchronized (this) {
			for(int i=0;i<10;i++) {
				Thread.sleep(10);
				System.out.println(Thread.currentThread().getName());
			}
		}
		
	}
	public static void main(String[] args) throws InterruptedException {
		Solution3 solution=new Solution3();
		new Thread(()->{
			try {
				Solution3.run1();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}).start();
		
		new Thread(()->{
			try {
				solution.run2();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}).start();
		
		Thread.sleep(2000);
	}
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/344816.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号