线程不安全:程序在多线程的执行环境下,程序的执行结果与与其结果不相符成为线程不安全。
一、导致线程不安全的原因
1.线程争抢,抢占式执行: 在并发编程中,由于不恰当的执行时序而出现不正确的结果,或者说当某个计算的正确性取决于多个线程的交替执行时序时,那么就会发生竞态条件。也可以说是正确的结果要取决于运气。
2.多个线程同时修改了同一个变量: 串行访问意味着多个线程依次以独占的方式访问对象,而不是并发地访问。
3.操作非原子性操作: 一种不可分割的操作,比如加了 synchronized 的同步代码块、一些原子变量类(AtomicLong等)。由锁保护的同步代码块会以原子方式执行,多个线程同时执行该代码块时也不会相互干扰。
4.内存可见性问题: 可见性是指当一个线程修改了共享变量的值,其他线程能够立即得知这个修改。
5.指令重排序:Java编程语言的语义允许Java编译器和微处理器进行执行优化,当多线程的时候这些优化导致了与其交互的代码不再同步,从而导致看似矛盾的行为。
二、解决线程安全问题的方法
1.volatile解决指令重排序问题和内存可见性问题。
(1)volatile可以解决指令重排序问题和内存可见性问题,代码在写入volatile修饰变量的时候 改变线程工作内存的volatile变量副本的值 将改变后副本的值从工作内存刷新到主内 (2)代码在读取volatile修饰的变量的时候
从主内存中读取volatile变量最新值到线程的工作内存中 从工作内存中读取volatile变量的副本
2.使用锁解决线程安全问题
主要有两种锁:
1.内置锁synchroned
(1)修饰静态方法
(2)修饰普通方法
(3)修饰代码块
2.lock()锁