面试官:谈谈你对synchronized的了解?

简介: 面试官:谈谈你对synchronized的了解?

我们来说说什么是互斥锁,互斥锁顾名思义就是相互排斥的锁,具体到我们Java语义就是加了这个锁之后同一个时刻只有一个线程执行这一块代码不管你是几个CPU,不管你多少线程,反正此时只能有一个线程执行!


image.png


基本上我们把需要互斥执行的那些代码称为临界区。


而我们的锁就是我们进入临界区的凭证!哪个线程获得锁就能单独的进去这个临界区在里面"为所欲为",而没得到锁的线程呢,你只能乖乖的在临界区外等着了!等到之前一个线程执行完毕了,释放了这个锁,才轮到你。


其实这个锁的本质实现就是:当一个线程获取到锁就是把它的线程id写入锁对象的对象头,来判断唯一。


所以当你有共享资源在多线程中相互竞争的时候你就能那这个互斥锁来保护你的共享资源,保证程序的正确性。


我们再来看看Synchronized,相信很多同学平日里也用过,Synchronized是Java中的关键字可以修饰方法或者代码块。


要注意一下如果我们的synchronized修饰的是静态方法,那表明锁的是当前的Class对象,如果修饰的不是静态方法,那表面锁的是当前的实例对象this。如果你用Synchronized(对象A),那当然你锁的就是这个对象A了。


这点其实会被很多同学忽略掉,我们上代码


image.png

看起来好像很完美,修改和获取方法都加了锁了。肯定线程安全了!


然而并不是的!


我们的静态方法加锁的代码其实就是等于synchronized(A.class);


而addOne()的加锁其实是synchronized(this)。所以两个方法就根本不是一个锁。那自然而然就保证不了安全了!


所以只有加的是同一个锁的时候才能保证有关联的共享资源(在我们代码中就是a),才会被正确的获取和修改!


image.png

所以改成这样就对了!


所以从上面我们可以得到一个结论,对一个资源的保护必须是同一个锁!但是呢如果是没有关联性的资源我们要细分粒度,比如以下代码

image.png

可以看到a和b没有任何的关联,这种情况下我们这样锁就导致了4个方法都互斥了!也就说同一时间4个方法只能有一个被执行!比如有个线程在addOneA,另一个线程在getB(),它竟然还得等addOneA结束。你看多捞啊!


所以呢在这种情况下我们需要细粒度的加锁!区分出没有关联的资源!


image.png

这样的话就能提升一下性能了!但是这样加锁我们的get和addOne是互斥的,在高并发的情况下就大大的不好了!性能太差了!所以一般情况下我们都CAS等一些其他手段去搞!还有注意细粒度锁可能会产生死锁!这里就不展开说了,之后我会专门搞一篇说说这些的。


是不是觉得差不多懂了?我们来看看下面的代码,经典的转账



image.png

image.png

锁也加了,看起来好像没问题?仔细想想看

有问题吧!这个锁是加在this上的!假设有A,B,C三个人,他们的余额分别是200,300, 400。这时候A要转账给B100,B要转给C100。


因为锁是加this上也就是实例对象上,而A,B,C就是3个实例对象所以他们各自加锁!假设A转B(线程1,此时的锁的是A.this)和B转C(线程2,此时锁的是B.this)是同时转的,你看两个锁不是同一个所以这两个线程能同时的进去transfer方法。那这情况就是B的钱要么是400,要么是200,反正怎么滴不会是300!


看完上面的我想你一定会对Synchronized有了深入的理解!希望对你有所帮助!



相关文章
|
6月前
|
存储 Java 开发者
面试官:小伙子知道synchronized的优化过程吗?我:嘚吧嘚吧嘚,面试官:出去!
面试官:小伙子知道synchronized的优化过程吗?我:嘚吧嘚吧嘚,面试官:出去!
69 1
|
6月前
|
Java
【面试问题】Synchronized 和 ReentrantLock 区别?
【1月更文挑战第27天】【面试问题】Synchronized 和 ReentrantLock 区别?
|
4月前
|
缓存 安全 算法
Java面试题:如何通过JVM参数调整GC行为以优化应用性能?如何使用synchronized和volatile关键字解决并发问题?如何使用ConcurrentHashMap实现线程安全的缓存?
Java面试题:如何通过JVM参数调整GC行为以优化应用性能?如何使用synchronized和volatile关键字解决并发问题?如何使用ConcurrentHashMap实现线程安全的缓存?
38 0
|
19天前
|
存储 安全 Java
面试题:再谈Synchronized实现原理!
面试题:再谈Synchronized实现原理!
|
3月前
|
存储 安全 Java
【多线程面试题十七】、如果不使用synchronized和Lock,如何保证线程安全?
这篇文章探讨了在不使用`synchronized`和`Lock`的情况下保证线程安全的方法,包括使用`volatile`关键字、原子变量、线程本地存储(`ThreadLocal`)以及设计不可变对象。
|
3月前
|
Java
【多线程面试题十五】、synchronized可以修饰静态方法和静态代码块吗?
这篇文章讨论了Java中的`synchronized`关键字是否可以修饰静态方法和静态代码块,指出`synchronized`可以修饰静态方法,创建一个类全局锁,但不能修饰静态代码块。
|
3月前
|
Java 调度
【多线程面试题十四】、说一说synchronized的底层实现原理
这篇文章解释了Java中的`synchronized`关键字的底层实现原理,包括它在代码块和方法同步中的实现方式,以及通过`monitorenter`和`monitorexit`指令以及`ACC_SYNCHRONIZED`访问标志来控制线程同步和锁的获取与释放。
|
3月前
|
Java
【多线程面试题十三】、说一说synchronized与Lock的区别
这篇文章讨论了Java中`synchronized`和`Lock`接口在多线程编程中的区别,包括它们在实现、使用、锁的释放、超时设置、锁状态查询以及锁的属性等方面的不同点。
|
4月前
|
安全 Java
Java面试题:解释synchronized关键字在Java内存模型中的语义
Java面试题:解释synchronized关键字在Java内存模型中的语义
46 1
|
4月前
|
安全 Java API
Java面试题:解释synchronized关键字在Java中的作用,并讨论其使用场景和限制。
Java面试题:解释synchronized关键字在Java中的作用,并讨论其使用场景和限制。
35 0