并发-基础

并发:同一CPU执行多个代码,通过时间片进行频繁的线程上下文切换。

并行:多个cpu同时执行多个程序。

上下文切换:通过给每个线程分配cpu时间片来实现这个机制,时间极短,看起来像是多个线程同时进行。通过时间片分配算法来循环执行任务,一个线程的时间片执行完后切换下一个线程执行,切换前会保存上一个任务的状态,下次切换到自己后,加载这个任务状态,继续执行。任务保存到再加载的过程就是一个上下文切换。多线程不一定快,上下文的切换会有开销。

 

如何减少上下文切花:

  • 无锁并发编程,多线程竞争锁时,会引起上下文的切换。避免使用锁----将数据id按照hash取模分段,不同线程处理不同段的数据。
  • 使用CAS算法。
  • 使用最少的线程,避免创建不需要的线程。
  • 协程,单个线程里实现多任务的调度,单线程内维持多个任务的切换。

避免死锁:

  • 避免一个线程占用多个锁资源
  • 使用定时锁

Validate:

轻量级的synchronized,保证共享变量的可见性,一个线程修改,另一个线程能够读取到这个修改的值。不会引起上下文的切换,执行成本低。语义:为了确保共享变量能被准确和一致地更新,线程应该确保通过排他锁单独获取这个变量。

  • 内存屏障:通过指令实现对内存操作的顺序限制
  • 缓冲行:cpu高速缓存中可分配的最小存储单位,
  • 原子操作:不可中断地一个或一系列操作
  • 缓存行填充:当处理器识别到从内存中读取操作数是可缓存的,处理器读取整个高速缓存行到适当的缓存。
  • 缓存命中:进行缓存填充时,内存位置仍然是下次处理器访问的地址,则从缓存行中读取---则缓存命中,而不是从内存中读取。
  • 写命中:将操作数写回内存缓存时,会检查这个缓存的内存地址是否在缓存,存在则写回到缓存,而不是写回内存--写命中。
  • 写缺失:有效的缓存行被写入不存在的内存区域。

volatile----引起两个操作:1.将当前处理器缓存行的数据写回到内存系统,2.这个写回内存的操作会使其他cpu里缓存了该内存地址的数据无效。

  ----为了提高速度,处理器不直接与内存通信,而是先将系统内存的数据读到内部缓存(L1,L2等)后再进行操作,但操作是不知道何时会写到内存,如果声明了volatile,则会发送一条lock前缀指令,将这个缓存行的数据写回到系统,为了保证多处理器下缓存的数据保持一致性,就会实现缓存一致性协议,每个处理器会嗅探在总线上传播的数据来检查自己缓存的值是否过期,如果发现自己缓存行中对应的内存地址数据被修改了,把当前缓存行置为无效,当处理器再存读取时,就会重新从系统内存中将最新的数据读取到处理器缓存里。

两个原则:

  1. Lock前缀指令引起处理器缓存写回到内存,lock信号确保处理器能够独占任何共享内存。锁定这块内存区域的缓存行并写回内存,同时使用缓存一致性机制来确保修改的原子性,同时阻止修改由两个以上处理器缓存的内存区域。
  2. 一个处理器的缓存回写到内存会导致其他处理器的缓存无效。MESI控制协议,使用嗅探技术保证它的内部缓存、系统内存和其他处理器的缓存的数据在总线上保持一致。

什么时数据总线

CPU总线,是PC系统中最快的总线,也是芯片组与主板的核心。这条总线主要由CPU使用,用来与高速缓存、主存和北桥(或MCH)之间传送信息。

synchronized:

作用:

  1. 确保线程互斥的访问同步代码
  2. 保证共享变量的修改能及时可见
  3. 有效解决重排序问题

synchronized的表现形式

  1. 对于普通方法同步,锁就是当前调用该方法的对象。
  2. 对于静态同步方法,锁就是当前类的class对象,一个类只有一个class对象。
  3. 对于同步方法块,锁是synchronized括号中配置的对象。

jvm中实现的原理:jvm基于进入和退出Monitor对象来实现方法同步和代码块同步,两种实现方式不同。monitorenter指令是在编译后插入到同步代码块的开始位置,monitorexit则是插入到方法结束处和异常处,jvm要保证enter和exit命令成对匹配,任何对象都有一个monitor与之关联,当一个monitor被持有,他将处于锁定状态,线程执行到enter时会尝试获取该对象所对应的monitor所有权,即尝试获得该对象的锁。

   字节码  同步代码块是通过 获取对象的monitor,
每个对象有一个监视器锁(monitor)。当monitor被占用时就会处于锁定状态,线程执行monitorenter指令时尝试获取monitor的所有权,过程如下:
1、如果monitor的进入数为0,则该线程进入monitor,然后将进入数设置为1,该线程即为monitor的所有者。
2、如果线程已经占有该monitor,只是重新进入,则进入monitor的进入数加1.
3.如果其他线程已经占用了monitor,则该线程进入阻塞状态,直到monitor的进入数为0,再重新尝试获取monitor的所有权。

执行monitorexit的线程必须是objectref所对应的monitor的所有者。
指令执行时,monitor的进
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值