一、线程安全
1、什么是线程不安全
当多个线程对同一个资源操作,结果跟我们预想的一样,就是线程安全,反之就是线程不安全
2、如何保证线程安全
- 同步方法
public synchronized void test() {}
- 同步代码块
synchronized (同步锁){
执行的代码块
}
- 锁机制
class TestThread implements Runnable{
int i = 0;
@Override
public synchronized void run() {
lock.lock(); // 获取锁对象
try {
i++;
System.out.println(Thread.currentThread().getName() + i);
// Thread.sleep(2000);
}catch(Exception e){
e.printStackTrace();
} finally {
lock.unlock(); // 释放锁对象
}
}
private final Lock lock = new ReentrantLock(); // ReentrantLock是Lock的子类
}
3、线程同步导致的问题
- 一个线程持有锁,其他线程等待,优先级倒置,导致性能低下
- 优先级高的等待优先级低的线程释放锁,导致性能导致
- 多线程竞争下,加锁释放锁导致上下文切换和调度延时,也会导致性能低下
二、死锁
1、什么是死锁
两个或两个以上的线程在执行过程中,由于竞争资源而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去
2、死锁的条件
- 互斥:共享资源1和共享资源2只能被一个线程持有
- 循环等待:线程1等待线程2持有的资源,线程2等待线程1持有的资源
- 占有且等待:线程在等待资源2而阻塞时,对持有的资源1保持不释放
- 不可抢占:线程持有的资源未释放,其他线程不可抢占
3、避免死锁的方法
破坏死锁产生的条件中的任意一个,便可避免死锁
- 互斥:无法破坏
- 循环等待:按序申请资源,反序释放资源
- 占有且等待:一次申请所有的资源
- 不可抢占:占有资源的线程如果在申请资源时,申请不到,可以主动释放所持有的资源