一、同步思想概述
(1)为什么要使用线程同步呢?
●为了解决线程安全问题
(2)上篇文章中取钱案例出现问题的原因?
●多个线程同时执行,发现账户都是够钱的。
(3)如何才能保证线程安全呢?
●让多个线程实现先后依次访问共享资源,这样就解决了安全问题
(3)线程同步的核心思想是什么?
●加锁,把共享资源进行上锁,每次只能一个线程进入访问完毕以后解锁,然后其他线程才能进来。
二、线程同步方式一:同步代码块
(1)作用
●把出现线程安全问题的核心代码给上锁
(2)原理
●每次只能一个线程进入,执行完毕后自动解锁,其他线程才可以进来执行
(3)格式
(4)具体使用
使用同步代码块把出现线程安全问题的核心代码给上锁,运行时就不会出现银行倒贴100000的情况啦~
(5)锁对象要求
●理论上:锁对象只要对于当前同时执行的线程来说是同一个对象即可
(6)锁对象用任意唯一的对象好不好呢?
●不好,会影响其他无关线程的执行
(7)锁对象的规范要求
●规范上:建议使用共享资源作为锁对象。
●对于实例方法建议使用this作为锁对象。
●对于静态方法建议使用字节码(类名.class)对象作为锁对象。
对于实例方法:
对于静态方法:
(8)同步代码块是如何实现线程安全的?
●对出现问题的核心代码使用synchronized进行加锁
●每次只能一个线程占锁进入访问
三、线程同步方式二:同步方法
(1)作用
●把出现线程安全问题的核心方法给上锁
(2)原理
●每次只能一个线程进入,执行完毕以后自动解锁,其他线程才可以进来执行
(3)格式
(4)具体使用
(5)同步方法底层原理
●同步方法其实底层也是有隐式锁对象的,只是锁的范围是整个方法代码。
●如果方法是实例方法:同步方法默认用this作为的锁对象。但是代码要高度面向对象!
●如果方法是静态方法:同步方法默认用类名.class作为的锁对象。
(6)同步方法是如何保证线程安全的?
●对出现问题的核心方法使用synchronized修饰
●每次只能一个线程占锁进入访问
(7)同步方法的同步锁对象的原理?
●对于实例方法默认使用this作为锁对象。
●对于静态方法默认使用类名.class对象作为锁对象。
(8)是同步代码块好还是同步方法好一点?
●同步代码块锁的范围更小,同步方法锁的范围更大。
四、线程同步方式三:Lock锁
(1)Lock锁概述
●为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock,更加灵活、方便。
●Lock实现提供比使用synchronized方法和语句可以获得更广泛的锁定操作。
●Lock是接口不能直接实例化,这里采用它的实现类ReentrantLock来构建Lock锁对象。
方法名称 | 说明 |
---|---|
public ReentrantLock() | 获得Lock锁的实现类对象 |
(2)Lock的API
方法名称 | 说明 |
---|---|
void lock() | 获得锁 |
void unlock() | 释放锁 |
(3)具体使用