Fork me on GitHub

并发编程 - 对象及变量的并发访问

注意:所有文章除特别说明外,转载请注明出处.

[TOC]

第二章 对象及变量的并发访问

2.1 synchronize 同步方法

2.1.1 方法内的变量是线程安全

提示:方法中变量不存在非线程安全问题,永远都是线程安全的。这是方法内部变量的私有属性造成的。

2.1.2 实例变量非线程安全

2.1.6 synchronize锁重入

关键字 synchronize 拥有锁重入的功能,也就是在使用 synchronize 时,当一个线程得到一个对象锁后,再次请求此对象锁时是可以再次得到该对象的锁的。

那么表示一个 synchronize 方法/块内部调用本类的其它 synchronize 方法/块时,是永远可以得到锁的。

提示:可重入锁是指:自己可以再次获取自己的内部锁。可重入锁也支持父子类继承的环境。

2.1.7 将任意对象作为对象监视器

多个线程调用同一个对象中的不同名称的 synchronize 同步方法或 synchronize(this) 同步代码块时,调用的效果就是按照顺序执行的,也就是同步的,阻塞的。

Java还支持任意对象作为对象监视器来实现同步功能,这个任意对象大多数是实例变量及方法参数,使用格式是:synchronize(非this对象)。

锁非this对象具有的优点:如果在一个类中很多个synchronize方法,这时虽然能实现同步,但是会受到阻塞,所以影响运行效率。但是如果使用同步代码块锁非this对象,则 synchronize(非this对象) 代码块中程序与同步方法是异步的,不与其他锁 this同步方法争抢 this锁,可提高效率。

提示:使用 synchronize(非this对象)同步块格式进行同步操作时,对象监视器必须是同一个对象,如果不是同一个对象监视器,运行的结果就是异步调用了,会交叉运行。

2.1.8 3个结论

1.当多个线程同时执行 synchronize(x){} 同步代码块时呈现同步效果。

    同步的原因是因为使用了同一个 对象监视器,如果使用不同的对象监视器会异步输出。

2.当其它线程执行x对象中 synchronize 同步方法时呈现同步效果。

3.当其它线程执行x对象方法里面的 synchronize(this) 代码块时也呈现同步效果。

注意:如果其它线程调用不加 synchronize 关键字的方法时,还是异步调用。

2.1.9 静态同步 synchronize 方法与 synchronize(class) 代码块

在静态方法上加关键字 synchronize 实现的效果和非static方法效果一样。但在本质上是不同的,synchronize 关键字加到static静态方法上是给Class类上锁,而synchronize 关键字加到非static方法上是给对象上锁。

2.1.10 同步方法容易造成 synchronize 方法无限等待

对于这样的方法,提供多个锁解决问题,如果一个synchronize方法内部陷入死循环状态,只有该方法进入死锁状态,而其它被 synchronize关键字修饰的方法不会进入死锁状态,获取它们方法的锁正常执行。

2.1.11 多线程的死锁

Java线程死锁是一个经典的问题,因为不同的线程都在等在根本不可能被释放的锁,从而导致所有的任务都无法继续完成。

2.1.16 锁对象的改变

在将任何数据类型作为同步锁时,需要注意的是,是否有多个线程同时持有锁对象,如果同时持有相同的锁对象,则这些线程之间是同步的。如果分别获得锁对象,则这些线程是异步的。

2.2 volatile关键字

2.2.1 volatile关键字和synchronize关键字的比较

1.关键字 volatile 是线程同步的轻量级实现,所以volatile性能肯定比 synchronize 关键字好,并且volatile只能修饰变量,而synchronize关键字可以修饰方法,以及代码块。

2.多线程访问volatile不会发生阻塞,而synchronize会发生阻塞。

3.volatile能够保证数据的可见性,但是不能保证原子性。synchronize可以保证原子性,也可以间接保证可见性。

4.关键字 volatile 解决的是变量在多线程之间的可见性,而synchronize关键字解决的是多个线程之间访问资源的同步性。

提示:线程安全包括原子性和可见性两个方面,Java同步机制围绕着两方面保证线程安全的。

本文标题:并发编程 - 对象及变量的并发访问

文章作者:Bangjin-Hu

发布时间:2019年10月15日 - 09:22:26

最后更新:2020年03月29日 - 11:39:21

原始链接:http://bangjinhu.github.io/undefined/第二章 对象及变量的并发访问/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

Bangjin-Hu wechat
欢迎扫码关注微信公众号,订阅我的微信公众号.
坚持原创技术分享,您的支持是我创作的动力.