【本人秃顶程序员】synchronized锁住的是代码还是对象

←←←←←←←←←←←← 快!点关注

不同的对象

public class Sync {
	public synchronized void test() {
		System.out.println("test start");
		try {
			Thread.sleep(5000);
		}
		catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("test end");
	}
}
public class MyThread extends Thread{
	public void run() {
		Sync sync = new Sync();
		sync.test();
	}
	public static void main(String[] args) {
		for (int i = 0; i < 3; ++i) {
			Thread thread = new MyThread();
			thread.start();
		}
	}
}

执行结果

test start
test start
test start
test end
test end
test end  

现象

在MyThread中,每次都new一个新的Sync对象,可以看到代码块test虽然被加了synchonized但是还是并行执行的,初步结论:锁住的不是代码块

同一个对象

public class MyThread2 extends Thread{
	public Sync sync;
	MyThread2(Sync sync) {
		this.sync = sync;
	}
	public void run() {
		System.out.println("hi....");
		sync.test();
	}
	public static void main(String[] args) {
		Sync sync = new Sync();
		for (int i = 0; i < 3; ++i) {
			Thread thread = new MyThread2(sync);
			thread.start();
		}
	}

执行结果

hi....
test start
hi....
hi....
test end
test start
test end
test start
test end  

现象

可以看到当他们共用一个对象的时候,synchonized起了作用,这块代码是串行执行的

结论

锁住的是对象

如何在多对象的时候任然锁住代码?

解决也很简单,只要锁住同一个对象就行了。例如:synchronized后的括号中锁同一个固定对象,这样就行了。

这样是没问题,但是,比较多的做法是让synchronized锁这个类对应的Class对象。

public class Sync2 {
	public void test() {
		synchronized (Sync2.class) {
			System.out.println("test start");
			try {
				Thread.sleep(2000);
			}
			catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("test end");
		}
	}
}
public class MyThread3 extends Thread{
	public void run() {
		Sync2 sync = new Sync2();
		sync.test();
	}
	public static void main(String[] args) {
		for (int i = 0; i < 3; ++i) {
			Thread thread = new MyThread3();
			thread.start();
		}
	}
}

执行结果

test start
test end
test start
test end
test start
test end

synchronized的两大不足

  • 由于我们没办法设置synchronized关键字在获取锁的时候等待时间,所以synchronized可能会导致线程为了加锁而无限期地处于阻塞状态
  • 使用synchronized关键字等同于使用了互斥锁,即其他线程都无法获得锁对象的访问权。这种策略对于读多写少的应用而言是很不利的,因为即使多个读者看似可以并发运行,但他们实际上还是串行的,并将最终导致并发性能的下降。

虽然synchronized已经作为一个关键字被固化在Java语言中了,但它只提供了一种相当保守的线程安全策略,且该策略开放给程序员的控制能力极弱

读者福利:

分享免费学习资料

针对于Java程序员,我这边准备免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)

为什么某些人会一直比你优秀,是因为他本身就很优秀还一直在持续努力变得更优秀,而你是不是还在满足于现状内心在窃喜!希望读到这的您能点个小赞和关注下我,以后还会更新技术干货,谢谢您的支持!

资料领取方式:加入Java技术交流群963944895,私信管理员即可免费领取

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值