线程同步相关知识详解。
一、同步代码块
作用:把出现线程安全问题的核心代码给上锁
原理:每次只能一个线程进入,执行完毕后自动解决,其他线程才可以进来执行。
synchronized(同步锁对象) {
操作共享资源的代码(核心代码)
}
锁对象要求
理论上:锁对象只要对于当前同时执行的现成来说是同一个对象即可。
锁对象用任意唯一的对象好不好呢?
不好,会影响其他无关线程的执行。
锁对象的规范要求
规范上:建议使用共享资源作为锁对象。
对于实例方法建议使用this作为锁对象。
对于静态方法建议使用字节码(类名.class)对象作为锁对象。
总结一下:
同步代码是如何实现线程安全的?
对出现问题的核心代码使用synchronized进行加锁
每次只能一个线程占锁进入访问
同步代码块的同步锁对象有什么要求?
对于实例方法建议使用this作为锁对象。
对于静态方法建议使用字节码(类名.class)对象作为锁对象。
二、同步方法
作用:把出现线程安全问题的核心方法给上锁。
原理:每次只能一个线程进入,执行完毕以后自动解锁,其他线程才可以进来执行。
格式:
修饰符 synchronized 返回值类型 方法名称(形参列表) {
操作共享资源的代码
}
同步方法底层原理
同步方法其实底层也是有隐式锁对象的,只是锁的范围是整个方法代码。
如果方法是实例方法:同步方法默认用this作为的锁对象。但是代码要高度面向对象!
如果方法是静态方法:同步方法默认用类名.class作为的锁对象。
是同步代码块好还是同步方法好一点?
同步代码块锁的范围更小,同步方法锁的范围更大。
总结一下
同步方法是如何保证线程安全的?
对出现问题的核心方法使用synchronized修饰
每次只能一个线程占锁进入访问
同步方法 的同步锁对象的原理?
对于实例方法默认使用this作为锁对象。
对于静态方法默认使用类名.class对象作为锁对象。
三、Lock锁
为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock,更加灵活、方便。
Lock实现提供比使用synchronized方法和语句可以获得更广泛的锁定操作。
Lock是接口不能直接实例化,这里采用它的实现类ReentrantLock来构建Lock锁对象。
Lock的API