文章目录
解决线程安全问题的三种方案:同步代码块、同步方法、使用 Lock
一、同步代码块
- 一、同步代码块
- 二、同步方法
- 静态同步方法
- 三、Lock
synchronized(同步锁对象) {
需要同步操作的代码
}
注: 1.锁对象可以是任意对象 2.必须保证多个线程使用同一个锁对象
问:为什么随便放个对象,就可以锁住代码块呢?什么原理?
二、同步方法public synchronized void method() {
可能会产生线程安全问题的代码
}
注:同步方法默认使用当前对象作为锁对象,也就是当前方法的所属实例对象,即 this
public static synchronized void method() {
可能会产生线程安全问题的代码
}
注:锁对象是当前类的 Class
对象。
Lock
是一个接口,其中有两个抽象方法:
public abstract void lock(); // 获取锁
public abstract void unlock(); // 释放锁
在存在线程安全问题的代码所在类中,声明定义一个成员变量,变量存放接口 Lock
实现类对象的内存地址,如下所示:
Lock lock = new ReentrantLock(); // ReentrantLock 是接口 Lock 的实现类
然后在存在线程安全问题的代码执行前加锁
lock.lock();
代码执行结束后,释放锁:
lock.unlock();
建议:将 lock.unlock()
放在 finally {}
语句块中,无论是否出现异常都会释放锁