高并发之Synchronized的理解

作用:能够保证在同一时刻最多只有一个线程执行该段代码,以达到保证并发安全的效果。

地位:java关键字,是最基本的互斥同步手段,并发编程中必学

不使用并发:例如,我们做一个简单的累加,累加10万次,利用两个线程,那么应该一共是累加到20万,

但是实际结果我们会发现,根本不会到20万,基本到是14万这种的,这就是没有使用Synchronized导致的后果。在每次累加的时候,一次累加包含读取值,加一,写入内存三个操作。例如,线程a在执行加一的时候,在读取值5,然后加一了变成6,在没有写入写存的时候,线程b就执行了读取值,这个时候读取的也是5,然后加一变成6写入内存,这也就是为什么两个线程在累加的时候,最终的结果会小于20万的原因了。这种情况,也就是我们通常所说的线程不安全,因为没有加锁。

方法锁:默认锁对象为this当前实例对象。

同步代码块锁:自己制定锁对象。

类锁:Synchronized修饰的静态方法或制指定锁为class对象。

在类中加入Synchronized,可以保证程序是串行执行的,如果没有加,那么代码块就会是并行执行,也就是会同时执行的。Synchronized(this){};最关键的就是锁的对象的选取,这里选取的是this,当前对象。对于需要锁住的对象,要根据具体的业务逻辑来选取。

多线程访问同步的七种情况:

1:两个线程同时访问一个对象的同步方法(串行,同一个实例,同一把锁,需要等待)

2:两个线程同时访问两个对象的同步方法(并行,锁的是不同对象)

3:两个线程访问的是Synchronized的静态方法(串行,只要是静态的,锁的对象就是同一把)

4:同时访问同步方法和非同步方法(同时执行,同时结束,并行)

5:访问同一个对象的不相同的普通同步方法(非静态)(一个先执行结束,后一个再执行结束,串行)

6:同时访问静态Synchronized方法和非静态Synchronized方法(同时开始,同时结束。锁指定的所对象不是同一个锁)

7:方法抛异常后,会释放锁(第一个线程异常,但是第二个线程可以运行,则说明锁释放了)

总结:

1.一把锁只能同时被一个线程获取,没有拿到锁的线程必须等待

2.每个实例都对应自己的一把锁,不同实例之间互不影响,锁对象是*.class以及synchronized修饰的static方法的时候,所有对象共用同一把类锁

3.无论是方法正常执行或者方法抛出异常,都会释放锁


©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容