一、出现线程安全问题的原因
出现线程安全问题的原因主要有五个方面:
- 操作系统对线程的调度是随机的/抢占式(主要原因)
- 多个线程修改同一个变量
- 修改操作不是原子的
- 内存可见性问题
- 指令重排序问题
二、如何解决
1.针对线程的抢占式执行,可以采用wait,notify来调配线程执行顺序。
2.对于多个线程修改同一个变量,可以调节代码结构,做到一定程度上的规避。
3.操作不是原子性,可以利用synchronized进行加锁操作,使操作变为原子性。
synchronized可以修饰代码块、方法、修饰静态方法(锁类对象)。锁具有互斥性,当一个线程对其加锁后,其他线程就不能够在对其进行修改或访问,需要等该线程释放锁后才能重新访问
4.内存可见性问题,是编译器优化引入的bug,当一个线程在修改一个内存数据时,另一个线程无法及时感知到,就会导致代码出现错误。使用volatile关键字修饰可能出现内存可见性问题的变量,就可以避免编译器只读寄存器不读内存的情况,解决了内存可见性问题
5.指令重排序也是编译器优化导致的bug,这里就不过多讲解了。
总结
线程安全问题时多线程中非常重要的一点,只有解决好线程安全问题,我们才能更放心的使用多线程。