高并发的三大特性

高并发的三大特性

引言

上一篇讲了线程的基础知识,谈到线程了,就会想到多线程与高并发,本篇就讲讲高并发的三大特性。

可见性

问题由来

线程用到堆中一个变量时,会copy一份使用,对其进行修改,不会立即刷新原值,若有其他线程用到这个值,会用到旧的值,造成数据不一致的问题。

解决方法

使用volatile修饰变量,会让所有线程都去堆内存中读取变量值

小实验

该程序中主线程和新的线程都用到了running变量。

主线程会对running的值进行改变。

对该变量加volatile与不加运行该程序,查看运行结果。

public class TestVolatile {

    private static boolean running = true; // 对该变量加volatile与不加运行该程序,查看结果

    private static void m() {
        System.out.println("m start");
        while (running) {
        }
        System.out.println("m end!");
    }

    public static void main(String[] args) throws InterruptedException {

       new Thread(TestVolatile::m, "t1").start();

        Thread.sleep(1000);

        running = false; 
    }
}

不加volatile。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yCnHeCXJ-1650283589632)(C:\Users\27901\AppData\Roaming\Typora\typora-user-images\image-20220417181600212.png)]

加volatile

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cHhpIRj1-1650283589634)(C:\Users\27901\AppData\Roaming\Typora\typora-user-images\image-20220417181646752.png)]

缓存行对齐

缓存行指的是CPU每个核读取数据时,一次读取64个字节。而多个核读取操作同一块数据时,为了保证数据一致性,cpu有缓存一致性协议,这样不可避免影响cpu效率。

为了保证避免一块数据被多个核读取,其中一个核只用到其中某些数据,而造成其他核频繁的同步这种情况。将数据进行缓存行对齐,保证每个核读取块中,只有其自己用到的数据。这种编程方式叫做缓存行对齐。

java实现方式

1.将要用到的变量长度为X,在其前面申请足够的变量,总长度为X1,使得X+X1 = 64字节。同理其后也是。

private long p1, p2, p3, p4, p5, p6, p7;
        public long x = 0L;
        private long p9, p10, p11, p12, p13, p14, p15;

2.直接使用@Contended注解,不过只有java1.8有效,且要配置虚拟机,去掉限制参数:-XX:-RestrictContended

有序性

问题由来

cpu为最大化利用其效率,会对指令进行重排序。

解决方法

volatile关键字

as-if-serial原则,保证单线程最后执行结果不变

happens-before原则

CPU内存屏障指令 lfence sfence mfence

JVM中的内存屏障,LoadLoadBarrier LoadStore SL SS

多线程环境下的有序性问题

这里注意new 对象底层其实有很多条指令的,并且会重排序,所以不要在构造方法中new 线程并启动,可能会在对象没new成功就取对象值,出现不可预估的结果。

原子性

问题由来

在并发操作同一变量的情况下,一个线程对数据的操作,被其他打断了。比如你操作一个变量,还没回写,又有别的线程来对它进行读操作了。

解决方法
  1. 对并发的代码块加锁。实质就是将并发操作编程序列化。加锁后的代码块具有原子性,解锁后会从线程刷回内存,保证了数据的可见性。
  2. java原子性指令
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

平平安安年年

一起学习,一起成长

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

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

打赏作者

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

抵扣说明:

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

余额充值