简单了解到java有几种方式实现线程安全的方式,synchronized和ReentrantLock。
synchronized是java的一个关键字,用于同步安全;分别有同步方式和同步代码块来解决同步安全问题。
ReentrantLock是jdk1.5后新出的一个类,解决同步安全的。
此处,我们引入一个例子来验证同步安全。
题目:现在有四个窗口来贩卖100张票,我们应该如何实现。
分析:四个窗口我们可以看成四个线程,100张门票是线程要共享的数据。
解决:
票对象
窗口对象
运行结果:由于没有考虑安全问题,出现了重票;
有三种改进方法:
第一种:添加同步代码块:synchronized(同步监视器){}
同步监视器:只能是对象,不限制对象类型;但多个线程必须使用同一个监视器才能有同步安全效果。
第二种:把方法改为同步方法,如果是静态同步方法同步监视器是类对象,非静态同步方法是当前类的实例对象
第三种:引入ReentrantLock对象,多个线程也要公用一个lock才会有同步安全。
synchronized和ReentrantLock异同点
相同:
- 都是解决同步安全的
不同:
- synchronized是关键字;ReentrantLock是一个类
- synchronized是自动解锁;ReentrantLock要手动加锁/解锁
使用时注意:千万根据实际情况来进行加锁且加锁范围要恰到好处,示例中的第二种方式同步范围过大只会有一个窗口在卖票,导致其他窗口不能卖。