【Java成王之路】EE初阶第三篇:(多线程3)

前言

接上一篇内容.......

产生线程不安全的原因~

5.指令重排序~(也是和编译器优化相关)

编译器会自动调整执行指令的顺序,以达到提高效率的效果

调整的前提是,保证指令的最终效果是不变的(如果当前的逻辑只是在单线程下运行.编译器判定顺序是否影响结果,就很容易.如果当前的逻辑可能在多线程下运行.编译器判定顺序是否影响结果.就可能出错)

(编译器优化,是一个非常智能的东西,哪怕程序猿代码写的很挫.但是编译器咔咔一顿优化,代码效率还是会挺高的)

如何解决线程不安全问题~ 

最普适的办法,就是通过"原子性"这样的切入点来解决问题

把一些不是原子性的操作变成原子性的操作

synchronized  英文原义"同步"

这里理解为"互斥"更合适

这个单词一定要会拼写,会念

这里我们继续来看之前用到的一个案例:两个线程分别针对count自增5w次

public class TestDome7 {
    static class Counter{
        public int count = 0;
       synchronized public void increase(){
            count++;
        }
    }
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        Thread t = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 50000; i++) {
                    counter.increase();
                }
            }
        };


        Thread t2 = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 50000; i++) {
                    counter.increase();
                }
            }
        };
        t.start();
        t2.start();

        t.join();
        t2.join();

        System.out.println(counter.count);
    }
}

 

如果两个线程同时并发的方式调用这个synchronized修饰的方法

此时一个线程会先执行这个方法,另外一个线程会等待,等到第一个线程方法执行完了之后,第二个线程才会继续执行

就相当于"加锁"和"解锁"

进入synchronized修饰的方法,就相当于加锁

出了synchronized修饰的方法,就相当于解锁

如果当前是已经加锁的状态,其他的线程就无法执行这里的逻辑,就只能阻塞等待

synchronized的功能本质上就是把"并发"变成"串行"

适当的牺牲一下速度,但是换来的是结果更加准确

多次打印结果:

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

K稳重

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值