java并发 三 概念和原理

一、概念

1、所有的并发只有2种:互斥(某种锁) +同步(某种条件)

2、互斥:只允许一个线程访问,jvm在调度时间片时使用

3、同步:应用间的协调,是应用为了实现某种逻辑而写的,一般基于互斥实现

4、POSIX中定义的工具:内存barrier(避免多核cache导致的不一致)、mutex、condition、readwritelock、semaphore

5、管程 monitor,把pv操作、加解锁抽象成数据结构,而不是散列在线程的代码里

6、io缓存:cpu用DMA缓存到内核,之后拷贝到用户空间,比不用缓存好的地方:不用多次分配和释放内存;可以一次让磁盘读入整个块;在读入的时候,使用更少的cpu干预。

7、内存映射:内核和用户空间使用同一个缓存,省了拷贝过程

8、JAVA NIO 直接buffer:不需要走jvm的堆,使用OS的内存

二、一些常识

1、Waiting VS blocked

waiting:程序员写的等待逻辑,切换时间片

blocked:io操作,竞争厉害的synchronized,sleep 等,导致线程等候,是jvm实现的

2、yield:还是runnable,但是暂时让jvm调度别人

3、java使用多线程的好处:

1>充分利用多核cpu 2>多个操作并发进行,提高响应速度,避免消息被堵住 3> 多线程IO的好处是可以充分利用内存cache和DMA,IO里面的逻辑可以并行。

4、使用多线程的坏处:1>上下文切换有成本(几十个到几百个clock):CPU寄存器需要保存和加载,系统调度器的代码需要执行,多核cache之间的共享数据 2> 占内存。3> IO DMA无法并行的情况下,多线程会降低吞吐率。

5、linux的"时间片"默认是0.75ms到6ms

6、main中没有非daemon线程时,会退出jvm进程;

7、安全的终止:在while循环里检查状态,而不是调用stop

 

三、java提供的工具(cache cas mutex/condition)

1、volatile(无锁):使寄存器缓存行失效,强制别的线程重新读内存(适用于一个线程写,多个线程读)

2、synchronized 互斥的逻辑,某种类型的锁(类似于管程),对应于上面的互斥。jvm的实现非常高效,具体的实现如下:

1》默认偏向锁:单线程执行时连lock的调用都不需要,直接在object的头部记录一个状态即可,实现层面仅仅添加了一个monitorenter指令。适合于大多数情况下,synchronized修饰的代码块都是单线程执行的情况,也可以认为是对单线程情况的优化。

2》轻量级锁(可重入、不可中断、非公平):有别的线程来竞争时升级为轻量级锁,用自旋(cpu空转)来等待别的线程释放锁(不切换时间片),适合于很快就会获得锁的情况(等一会时,这个时间片还没有结束)(jvm内部全部是轻量级锁)

3》重量级锁:自旋的时间很久时,使用重量级锁,需要切换时间片,避免空转(线程变为blocked)

3、原子操作 atomixXXX cas自旋的方式实现(不加锁)

4、wait(释放锁)/notify 对应于同步

程序员控制的线程之间的交互同步,而不是jvm的时间片调度。条件一定要加锁使用。wait会释放相应的锁,但是notify不会,notify执行后不会马上回到wait,而是等待竞争到锁之后才执行到wait的逻辑,获得条件后还需要检查状态。notify使线程由等待条件变成等待锁。

WaitQueue->SynchronizedQueue中

synchronized(lock){while(!flag){lock.wait();} do();}

synchronized(lock){change();lock.notifyall();}

5、piped 用于线程间传递数据(基于共享内存)

6、Thread类(只有wait释放锁)

join 内部也是加锁(synchronized),循环判断,wait

sleep/yield 让出cpu时间片,不释放锁

7、锁的公平性(fair):释放后一定放到队尾部,获取时一定从前往后;不公平获取,看上一次是否获取过。

8、线程挂起的原因:io、没有抢到时间片、没有获得锁

四、工具的扩展

1、锁:某种意义上的串行化。syncronized固化了使用方式,使用简单,但是不灵活。除了基本的同步需要,锁需要考虑 可重入?公平?互斥还是读写?非阻塞?超时?线程获取锁时是否可中断(不是一直阻塞在那)?更细的粒度?(默认全部是乐观锁) 这些灵活性通过java5的concurrent.lock包来实现(自己处理加解锁和死锁)。lock接口的灵活性 try lockInterruptibly r/w timeout

2、Synchronized语义:可重入、非公平、互斥、阻塞(不可中断,sleep时还会阻塞别的线程,自己死了锁还被保持着)、不能超时

3、锁的粒度:volatile < atomicXXX < CAS < 各种lock < wait

4、lock的扩展

ReentrantLock:可重入(递归),可中断(可实现获取就独占)

ReentrantReadWriteLock:读多写少时,粒度小,性能高。

StampedLock:避免太多读线程,使得写线程很难调度到,有写时应该先允许写,之后重新读就好了,考虑的是公平性

    AbstractQueuedSynchronizer:管理互斥共享阻塞队列、等候队列。tryacquire(Shared) getExclusiveQueuedThreads

isHeldExclusively release

阻塞的线程,是否响应中断?Interruptibly(不会移除同步队列)acquire 同步获取,得不到阻塞

5、wait/notify的扩展

      LockSupport:等待和解除等待(没有wait/notify时序要求)

park:  等待条件,不需要在unpark之前,

unpark: 释放一个条件

      condition:支持多个队列、超时和中断,synchronizer内部类

await(释放锁):怎么返回?被signal或被中断

signal:等待队列-->同步队列,只有再次获得锁才会执行wait后续的操作

 

总结:ReentrantReadWriteLock/StampedLock;condition/LockSupport

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值