什么是线程安全?线程安全问题形成的原因

本文探讨了线程安全问题的起源,包括线程调度的随机性、共享变量的并发修改、非原子操作和内存可见性、指令重排序等因素。通过实例分析了如何确保多线程环境下的代码正确性。
摘要由CSDN通过智能技术生成

 

目录

 

什么是线程安全

产生线程安全问题的原因:


什么是线程安全

整个多线程中最最重要、最最复杂的部分

什么是线程安全问题?

有些代码在单线程环境下执行,完全正确

让多个线程同时执行,此时就可能会出现bug

Thread t1 = new Thread(() -> {
            // 对 count 变量进行自增 5w 次
            for (int i = 0; i < 50000; i++) {
                synchronized (locker) {
                    count++;
                }
            }
        });
        Thread t2 = new Thread(() -> {
            // 对 count 变量进行自增 5w 次
            for (int i = 0; i < 50000; i++) {
                synchronized (locker) {
                    count++;
                }
            }
        });

        t1.start();
        t2.start();

        // 如果没有这俩 join, 肯定不行的. 线程还没自增完, 就开始打印了. 很可能打印出来的 count 就是个 0
        t1.join();
        t2.join();

        // 预期结果应该是 10w
        System.out.println("count: " + count);

但是打印的结果小于10000

原因:

count++ 这个操作,本质上,是分成三步进行的

①load 把数据从内存,读到 cpu 寄存器中,
②add把寄存器中的数据进行 +1
③save 把寄存器中的数据,保存到内存中

如果是多个线程执行上述代码,由于线程之间的调度顺序,是"随机"的,就会导致在有些调度顺序下,上述的逻辑就会出现问题

所以,多线程中,最困难的一点就是线程的随机调度,使两个线程执行逻辑的先后顺序,存在诸多可能我们必须要保证在所有可能的情况下,代码都是正确的!!!

产生线程安全问题的原因:

①操作系统中,线程的调度顺序是随机的 (抢占式执行).罪魁祸首,万恶之源

②两个线程,针对同一个变量进行修改

a一个线程针对一个变量线程修改 ok

b两个线程针对不同变量修改 ok

c两个线程针对一个变量读取 ok

③修改操作,不是原子的.

类似的,如果一段逻辑中,需要根据一定的条件来决定是否修改

④内存可见性问题.

⑤指令重排序问题.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值