2.1 synchronized同步方法


参考资料:《Java多线程编程核心技术》

以下内容是上述书籍对应章节的总结,有点抽象,可参考书籍中的代码:


Synchronized同步方法:


2.1.1方法内的变量为线程安全:

方法内部的变量是线程安全的,不存在“非线程安全”问题,因为方法内部的变量是私有的。所以当多个线程访问同一个实例的方法时,同时操作方法内部的变量,是线程安全的,不需要同步处理。


2.1.2实例变量非线程安全:

当多个线程访问同一个对象的实例变量时,在该对象的方法中操作实例变量,有可能出现“非线程安全”。这个时候方法就需要同步。
关键字synchronized取得的锁都是对象锁,而不是把一段代码或方法当做锁,所以哪个线程先执行带synchronized关键字的方法,哪个线程就持有该方法所属对象的锁Lock,那么其他线程只能呈等待状态,继而实现了同步,前提是多个线程访问的是同一个对象。


2.1.3多个对象多个锁:

当多个线程访问同一个类的两个不同实例的相同名称的同步方法(说明方法加了关键字synchronized),效果还是以异步方式运行的(即打印顺序不是同步的,是交叉的)。因为多个线程访问多个对象,JVM会创建多个锁。当然,不加锁的话,结果也是异步的,因为是访问多个对象。而不是同一个对象。


2.1.4synchronized方法与锁对象

牢牢记住“共享”两个字,只有共享资源的读写访问才需要同步化,如果不是共享资源,那么根本就没有同步的必要。
当两个线程(线程A和线程B)分别调用同一个类的相同实例的不同方法时(同步方法A和非同步方法B),结果是异步的。因为A线程先持有object对象的Lock锁,B线程可以异步的方式调用object对象中的非synchronized类型的方法。

如果我们把方法B加上synchronized的话,则结果是同步的。即A线程先持有object对象的Lock锁,B线程如果在这时调用object对象中的synchronized类型的方法则需要等待,也就是同步。这也验证了上面所说的关键字synchronized取得的锁都是对象锁,而不是把一段代码或方法当做锁。


2.1.5脏读

发生脏读的情况是在读取实例变量时,此值已经被其他的线程更改过了。比如设置变量值的方法是同步方法,而返回值的方法是非同步方法,这个时候就可能会出现“脏读”。解决办法,返回方法同样加上synchronized关键字。


2.1.6 synchronized锁重入

关键字synchronized拥有锁重入的功能,也就是在使用synchronized时,当一个线程得到一个对象锁后,再此请求此对象锁时是可以再次得到该对象的锁的。这也证明在一个synchronized方法/块的内部调用本类的其他synchronized方法/块时,是永远可以得到锁。

当存在父子类继承关系时,子类是完全可以通过“可重入锁”调用父类的同步方法的。


2.1.7出现异常,锁自动释放

出现异常的锁被自动释放了


2.1.8同步不具有继承性

同步不能被继承,还是得在子类的方法中添加synchronized关键字。和前面所说的子类是完全可以通过“可重入锁”调用父类的同步方法不冲突,因为“可重入”说明子类的方法必须是同步的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值