对象锁和类锁的区别

本文详细介绍了Java中的对象锁和类锁。对象锁锁定的是实例,不同实例间的锁互不影响;类锁锁定的是类的.class信息,是全局共享的。通过示例代码展示了加锁的不同方式及它们在多线程环境中的行为。
摘要由CSDN通过智能技术生成


生活中不存在绝对的自由,绝对的自由通常对应的无序和混沌,只有在道德、法律、伦理的约束下的相对自由,才能使人感受到自由。
而在多线程编程中,锁是至关重要的,锁就是道德,就是法律约束,没有锁的多线程环境将会是混乱的,所有线程都在争夺资源,最后的结果就是导致系统崩溃,而有了锁之后,多线程环境才能稳定高效的工作。

synchronized 关键字

synchronized 是我们所说的重量级锁,所说的重量级是相对于那些自旋锁(AQS)而言的,比如可重入锁ReentrantLock。很多人谈 synchronized 色变,说它性能差、太重,貌似言之凿凿。放在多年前确实如此,但是 Java 1.7、1.8 已经对 synchronized 做了很大优化,其性能和那些轻量级锁几乎没有差距。
所以,我们再程序中其实可以放心的使用它,即使没有用过,也肯定在一些源码里见过,比如 Netty 中就有很多地方用到了它。
下面开始进入今天的主题,类锁和实例锁。看名字就已经很明显了,类锁就是所在类上的锁,实例就是锁在类实例上的锁。

对象锁

类声明后,我们可以 new 出来很多的实例对象。这时候,每个实例在 JVM 中都有自己的引用地址和堆内存空间,这时候,我们就认为这些实例都是独立的个体,很显然,在实例上加的锁和其他的实例就没有关系,互不影响了。

通常我们使用实例锁的方式有下面三种:

1、锁住 this 对象

this 指的是当前对象实例本身,所以,所有使用 synchronized(this)方式的方法都共享同一把锁。
在这里插入图片描述

2、 锁住实体里的非静态变量

非静态变量是实例自身变量,不会与其他实例共享,所以锁住实体内声明的非静态变量可以实现对象锁。锁住同一个变量的方法块共享同一把锁。
在这里插入图片描述

3、直接锁非静态方法

最简单、最直观的一种方式,直接加在方法返回类型前。
在这里插入图片描述

使用对象锁的情况,只有使用同一实例的线程才会受锁的影响,多个实例调用同一方法也不会受影响。

对象锁代码测试

下面来做个测试,开启 5 个线程,每个线程都 new 一个新的实例来分别调用上面三种方式的方法,方法完成的动作就是输出线程名称,然后休眠 10 秒钟。

public class ObjectLock {
   

	private Object lock = new Object();
	
	/**     
	* 锁住非静态变量     
	* @throws InterruptedException     
	*/    
	public void lockObjectField() throws InterruptedException {
           
		synchronized (lock) {
               
			System.out.println(Thread.currentThread().getName());            
			Thread.sleep(10*1000);        
		}    
	}    

	/**     
	* 锁住 this 对象 this 就是当前对象实例     
	* @throws InterruptedException     
	*/    
	public void lockThis() throws InterruptedException {
           
		synchronized (this) 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值