线程安全:
多个线程同时操作同一份资源的时候,可能会遇到线程不安全问题,通过锁控制线程数据安全问题
同步锁
synchronized 关键字
关注点:
锁的对象内容->关心锁哪一个对象,能够锁住 同步的代码的范围--> 关心想要哪一个段代码多线程之后需要排序执行
同步的代码范围太大,效率太低,范围太小,可能不安全 锁的对象一定要锁不变的内容,不变的内容才能锁住
使用方式:
1.同步方法 : 在方法上synchronized修饰 静态方法 成员方法
2.同步块 使用synchronized修饰{} synchronized(锁的对象内容){ 排队执行的代码段... } 锁的对象内容 : this | 类.class | 资源
同步方法相对来说比同步块锁同步的代码范围更大,但是比较简单
单例模式中的懒汉式实现方式是线程不安全的-->可以通过同步锁实现
同步成员方法
代码范围: 整个方法体需要多线程之间排队执行 锁的对象: 成员方法属于对象的,相当于锁调用成员方法的那一个对象
缺点: 排序执行的代码范围可能较大,整个方法体,如果想要同步为方法中 的某一端代码,可以使用同步块
同步块
this|类|资源 synchronized(类}
特点:
锁类相当于锁了类的所有对象,每一个类型只有一个Class对象,唯一的不变的,在使用之前就存在的
synchronized(this){} 注意: 锁this在成员方法中默认指代锁的为当前调用成员方法的对象 锁this相当于锁了当前对象的所有成员资源,如果只想要锁一个资源,可以单独只锁这个资源,而非当前这个对象
synchronized(资源){ }
注意: 要求资源 为自定义的引用数据类型,锁的是资源唯一的对象地址 double check 双重检查 --> 为了提高执行效率
死锁
死锁是指两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,这些永远在互相等待的线程称为死锁线程。
线程通信
Object类中的方法: wait() 等待 : 当一个线程对象调用wait()方法,进入到相关对象的等待池中进行等待,等待阻塞状态,等待被唤醒 会释放cpu的资源,同时释放对象的锁 notify() 唤醒 : 唤醒对应对象等待池中正在等待的线程,如果存在多个唤醒某一个 被唤醒的线程会恢复到就绪状态,到底是否能够执行需要cpu的调用,并且获取对象的锁资源
wait()与notify()方法必须存在同步环境内部使用,因为控制多线程之后共享数据存储安全问题
sleep 线程休眠 抱着资源睡觉 : 会让出cpu的资源但是不会让出对象的锁资源
注意: 如果wait与notify没有在同步环境下使用,会抛出异常IllegalMonitorStateException远在互相等待的线程称为死锁线程。