多线程-- 一.并发基础与并发模拟

高并发概念:

    High Concurrency:是互联网分布式系统架构设计中必须考虑的因素之一,通常是指通过设计保证系统能够同时并行处理很多请求.

并发:多个线程操作相同的资源,保证线程安全,合理使用资源

高并发:服务能同时处理很多请求,提高程序性能


并发编程基础:

一.cpu多级缓存

    1.为什么需要CPU cache:因为CPU的频率太快了.快到主存跟不上,这样在处理器时钟周期内,CPU常常需要等待主存,浪费资源.所以cache的出现,是为了缓解CPU和内存之间速度的不匹配问题.

    2.CPU cache有什么意义:Modified Exclusive Shared Or Invalid

        1.时间局部性:如果某个数据被访问,那么在不久的将来它很可能被再次访问.

        2.空间局部性:如果某个数据被访问,那么与它相邻的数据很快也可能被访问.

    3.缓存一致性(MESI)协议

        用于保证多个CPU cache之间缓存共享数据的一致.

    M: 被修改(Modified)

    该缓存行只被缓存在该CPU的缓存中,并且是被修改过的(dirty),即与主存中的数据不一致,该缓存行中的内        存需要在未来的某个时间点(允许其它CPU读取请主存中相应内存之前)写回(write back)主存。当被写回主    存之后,该缓存行的状态会变成独享(exclusive)状态。

    E: 独享的(Exclusive)

    该缓存行只被缓存在该CPU的缓存中,它是未被修改过的(clean),与主存中数据一致。该状态可以在任何时刻当有其它CPU读取该内存时变成共享状态(shared)。同样地,当CPU修改该缓存行中内容时,该状态可以变成Modified状态。

    S: 共享的(Shared)

    该状态意味着该缓存行可能被多个CPU缓存,并且各个缓存中的数据与主存数据一致(clean),当有一个CPU修改该缓存行中,其它CPU中该缓存行可以被作废(变成无效状态(Invalid))。

    I: 无效的(Invalid)

    该缓存是无效的(可能有其它CPU修改了该缓存行)。

    4.乱序执行优化

        处理器为提高运算速度而做出违背代码原有顺序的优化.

二.Java内存模型(JMM) Java Memory Model

    1.它是一种规范,规范了Java虚拟机与计算机内存是如何协同工作的,规定了一个线程如何和何时可以看到其它线程修改过的共享变量的值,以及在必须时如何同步的访问共享变量.

    Java内存模型要求,调用栈,和本地变量,存放在线程栈上,对象存放在堆上.

    堆:Heap

        运行时的数据区,是由垃圾回收负责的

        优势:可以在运行期动态分配内存大小,生存期也不用提前告诉编译器,

        缺点:由于是运行时动态分配内存的,所以存取速度要相对慢一些

    栈:Stack

        栈中一般存基本类型的变量,例如 int short byte ...

        优势:存取速度比堆快,仅次于计算机里的寄存器.栈中的数据是共享的

        缺点:存在栈中的数据大小与生存期必须时确定的,缺乏一些灵活性

    2.同步操作过程图:

    一共是八种操作及规则:lock,read….

三.并发的优势与风险:


并发模拟

线程安全:简单来说,并发环境下,能得到我们想要的正确的结果,就是线程安全的.

并发模拟常用工具:Postman,ab,JMeter

并发模拟的常用类:

1.Semaphore类:

    信号量,它可以阻塞进程,并可以控制同一时间请求的并发量,通常与线程池一起使用.

    Semaphore semaphore = new Semaphore();

    两个方法:

    semaphore.acquire();

    semaphore.release();

    可以将acquire操作视为是消费一个许可,而release操作是创建一个许可,Semaphore并不受限于它在创建时的初始许可数量。

2.CountDownLatch类:

    计数器下减闭锁,位于java.util.concurrent包下,利用它可以实现类似计数器的功能。比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了。

    CountDownLatch countDownLatch = new CountDownLatch();

    countDownLatch.countDown();    当前计数器的值减1

    countDownLatch.await();    调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行

    

下图例子就是线程不安全的,得出的结果每次都是不一样的

(@NotThreadSafe是我们自己定义的一个直接,没实际意义,只是为了标注一下)

猜你喜欢

转载自blog.csdn.net/zhmystic/article/details/82117441
今日推荐