JavaSE基础day22 线程安全问题、锁
线程安全问题
问题的概述:
当多个线程使用并发原理操作同一个数据或者操作同一段代码时,就有可能造成的数据 错误或者代码的错误,类似的错误就是线程安全问题。
同步代码块
1、同步代码块:使用同步代码块括起来的代码,可以保证代码的完整性和一致性、原子性
2、格式:
synchronized(锁对象){
需要保证完整性的代码。
}
3、同步代码块特点:
如果某段代码使用了同步代码块。
线程想要执行这段代码,需要先获取锁对象,获取到锁对象之后,才可以执行,如果这 段代码没有执行完,锁对象不会被线程释放,当这段同步代码被线程执行结束之后,才 会释放锁对象。
4、总结:
(1)两段代码(两个线程)需要做到互不影响,这两个线程应该使用同一个锁对象
(2)this可以(优先), 类的字节码对象也可以(通用)
代码
同步方法
1、概念:如果一个方法中的所有内容都需要保持同步,可以使用同步方法来代替同步代码块以达到简化代码的操作。
2、格式:
修饰符 synchronized 返回值类型 方法名称(){
}
3、注意:
如果方法是一个非静态方法,那么锁对象默认为 this
如果方法是静态方法,锁对象默认为类.class
代码
卖火车票案例代码
Lock锁
1、概述:
虽然我们可以理解同步代码块和同步方法的锁对象问题,但是并不能直观看到线程在哪 里获取了锁,在哪里释放了锁,所以为了更清晰的展示如何加锁和释放锁,JDK5以后 提供了一个新的锁对象Lock,可以使用此对象,来表示锁的创建和释放。
2、构造方法:
ReentrantLock():创建一个ReentrantLock的实例
3、加锁解锁方法:
void lock() :获得锁
void unlock():释放锁
4、补充:
(1)Lock锁 同步代码块 同步方法,默认为非公平锁特点
非公平锁:设置的锁对象,是没多个线程之间获取的,有可能这个锁每次都被同一个线程获取,就导致代码都由一个线程完成,就表示其他线程可能没有执行的机会,或者执行的机会比较少。
公平锁:锁对象可以依次让每个线程获取,所以每个线程都有执行的机会
在创建Lock锁对象时,传递一个true参数,可以设置为公平锁
代码