JavaEE-线程安全专题
文章目录
- 线程安全概述
- 线程安全引入
- 线程不安全原因概述
- 线程是随机调度的
线程安全概述
线程安全引入
线程安全问题是整个多线程专题的最核心也是最重要的章节, 如果不理解线程的安全, 是无法写出正确的多线程的代码的, 我们之前所写的代码都是在单一的线程环境之下写出的 “玩具式” 的代码, 不存在多线程的复杂关系, 下面我们给出一段代码来引出线程安全的话题…
public class ThreadTest {
// 定义一个计数器
private static int count = 0;
// 定义一个循环的次数
private static final int MAX_TIME = 50000;
public static void main(String[] args) throws InterruptedException {
// 重置计数器count
count = 0;
// 创建线程t1
Thread t1 = new Thread(() -> {
for(int i = 0; i < MAX_TIME; i++){
count++;
}
});
// 创建线程t2
Thread t2 = new Thread(() -> {
for(int i = 0; i < MAX_TIME; i++){
count++;
}
});
// 开启线程t1, t2
t1.start();
t2.start();
// main线程等待t1, t2 的执行
t1.join();
t2.join();
System.out.println("运行结果" + count);
}
}
我们上述代码想要完成的逻辑是
- 想通过两个线程把
count
的值置为10_0000
但是实际上, 运行结果是
…
可以发现, 运行结果跟我们的预期的结果不一致, 这其实就是线程安全问题
线程安全问题:
在多线程环境下, 如果实际运行的结果与预期不一致, 就说明存在线程安全问题, 或者说线程不安全
线程不安全原因概述
- 线程是并发执行的, 在cpu上的调度的随机的…[根本原因]
- 多个线程同时修改同一个变量
- 修改操作不是原子性的
- 内存可见性问题
- 指令重排序问题
第一条的关于cpu的调度问题, 我们是没有办法干预的, 因为这是操作系统层面的事情, cpu是随机调度的, 而不是串行执行, 如果是串行执行则不会出现这种线程安全相关的问题
所以我们只能从后四个进行关于线程安全的处理
线程是随机调度的
这是线程安全问题的最根本的原因, 因为我们的程序在cpu上的执行是随机调度的, 所以天然的程序执行就不是连续的, 想要解决这种问题的方法就是, 重写一个操作系统(对线程的调度模式进行重新设计, 这显然是不合理的…)