跳到主要内容

三、线程安全

一、线程不安全

如果多线程环境下代码运行的结果是符合我们预期的,即在单线程环境应该的结果,则说这个程序是线程安全的。否则就称之为线程不安全。

线程不安全的原因:

> 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());
}
}