三、线程安全
一、线程不安全
如果多线程环境下代码运行的结果是符合我们预期的,即在单线程环境应该的结果,则说这个程序是线程安全的。否则就称之为线程不安全。
线程不安全的原因:
> 1. 抢占式执行,可以说“线程的无序调度”是罪魁祸首,万恶之源!!!(是操作系统内核来实现的,程序员无法控制) > 2. 多个线程修改同一个变量。 > 3. 修改操作,不是原子(不可分割的最小单位)的。某个操作对应单个cpu指令就是原子的,如果单个操作对应多个CPU指令,大概率不是原子的。正是因为不是原子的,导致多个线程的指令排列存在更多的变数。 > 4. 内存可见性,引起的线程不安全。 > 5. 指令重排列,引起的线程不安全。
二、线程不安全案例与解决方案
1、修改共享资源
> 即针对于多个线程修改同一个变量的情况,由于修改操作可能不是原子的(单条cpu指令),在多线程的随机调度下,就会导致多个线程的指令排列存在更多变数。
例如如下代码:
class Counter {
private int count = 0;
public void add() {
count++;
}
public int getCount() {
return count;
}
}
public class ThreadExample_unsafe {
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 50000; i++) {
counter.add();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 50000; i++) {
counter.add();
}
});
t1.start();
t2.start();
//等两个线程结束后查看结果
t1.join();
t2.join();
System.out.println(counter.getCount());
}
}