多线程开发之外练互斥

 

​认识两个关键字:synchronized和volatile,主要用来解决多线程数据安全问题。

 

synchronized

 

synchronized是一个同步锁,阻塞多线程并发访问一个方法或方法块,也就是线程必须同步访问资源。

1.对象锁

每个对象拥有一个synchronized锁。

上面两个线程同时访问一个没有同步的方法,造成数据的不安全(数据脏读),在方法加上synchronized之后再运行:

synchronized同步锁是一个对象监视器,在上面例子中,它锁住的是numRef对象,也就是在监视numRef对象,在这个对象中,所有加了synchronized的方法,都只能被持有锁的线程访问,其他的线程都会阻塞,而没有加synchronized的方法,可以被其他线程异步访问。

上面Run.java中,如果new了多个numRef对象,为每个线程分配一个,运行结果还是同步吗?结果肯定是异步的。

当一个线程得到一个对象锁后,再未释放锁之前,是可以再次访问此对象锁的,我们称为synchronized锁重入。

"可重入锁"的概念:自己可以再次获取自己的内部锁。

值得注意的是,当一个线程执行出现异常时,其所持有的锁会自动释放。

synchronized同步方法的另一种表达方式:同步方法块。synchronized(this)、synchronized(非this),this指代的当前对象。

用同步方法块可以更加灵活的运用synchronized锁。

由于对象监视器不同,一个是anyString对象,一个是service对象,所以运行结果是异步的。如果将synchronized(anyString)改成synchronized(this)就变成同步了。

当存在多个对象锁的时候,我们要特别注意死锁。

检测死锁的可以用jstack命令,这里就不详细介绍了,后续可以整理相应的学习笔记。

2.Class锁

Class锁是在静态方法上加synchronized,表达方式为:同步方法和同步方法块 synchronized(类名.class)。

每个类只有一个Class锁,所有的对象都共享这一个锁。

虽然是不同的service对象,但共享一个Class锁,所以同步运行。

如果在service里再加一个非静态同步方法,新启一个线程访问,会是异步的吗?肯定是异步的,因为一个是对象锁,一个是Class锁。

 

时间有限,volatile 再写啦。

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

 

 

更多推送文章请关注公众号:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值