前言
最近又把《Java并发编程的艺术》这本书,重读了一遍,感觉播种比上一次还大!因为在理论的学校学习中,Java并发这一块,其实并没有很罕用,然而恰好不巧的事,在企业中在理论生产中,并发编程是不可或缺的一块,所以重读这本书我觉得很有必要。最近感悟,学习是一件很高兴的事,每当读《Java并发》《JVM》时,感觉莫名的兴奋,对技术的激情还是有哒!我的《平庸的世界》还没有读完,wuwuw,等忙完这阵子也要补补了。
一、并发编程的挑战
1、上下文切换 (无锁并发编程(防止锁竞争),CAS算法,应用起码线程,协程)
2、死锁
- 条件:1、互斥条件 2、不可剥夺条件 3、申请与放弃条件 4、循环期待条件
- 解决:1防止同时取得多个锁 2防止一个锁内应用多个资源 3尝试应用定时锁 4数据库锁加锁和解锁在一个链接里
- Java:按序加锁、加锁时限、死锁检测(保护一个数据结构)
3、资源限度(硬件(上传下载 读写)(集群) 软件(连接数)(池化复用))
二、Java并发机制的底层实现
1、volatile
- ①Lock前缀指令会引起处理器缓存写会主内存
- ②处理器缓存写会主内存会使其余处理器的缓存生效
2、synchronized 1.6后优化
- 无锁: 偏差锁标识为0,则CAS获取偏差锁
- 偏差锁:偏差锁标识为1,锁对象记录线程ID,下次该线程获取时间接测试,失败则CAS尝试锁记录指向以后线程ID
- 敞开偏差锁,间接进入轻量级锁
- 轻量级锁:加锁:以后线程的栈帧中创立空间,对象头的MarkWord复制该空间,CAS尝试对象图的MW指向该空间,胜利则取得锁,失败则自旋获取锁;解锁:CAS操作将栈帧中的锁记录Displaced MarkWoed替换回对象头,胜利即解锁,失败则有竞争,收缩为重量级锁,阻塞竞争线程,本人开释锁并唤醒竞争线程
- 重量级锁:竞争线程阻塞,解锁后唤醒竞争线程
3、原子操作
- 锁(CAS形式开释获取锁)
- 自旋CAS(ABA(版本号)、循环开销、只保障一个共享变量的原子操作)
三、Java内存模型
- Java并发采纳共享内存模式(消息传递模式)隐式通信显示同步
- 主内存存储共享变量 每个线程有本地内存保留主内存的共享变量正本
四、Java并发根底
1、过程资源分配的最小单位、线程程序执行的最小单位 2、线程的状态 new->runnable(running、ready)->terminated waiting|time_waiting|blocked 3、中断线程interrupt 而不应用stop(不开释资源);也可在线程外部应用一个boolean变量 4、线程先获取监视器对象,获取失败则进入SynchronizedQueue wait->进入WaitQueue->notify->SynchronizedQueue? |5、t.join 以后线程进入wating态期待t线程执行完 波及期待告诉机制 给t加锁 让以后线程期待,t完结时唤醒以后线程 6、ThreadLocal线程本地变量 数据库连贯治理保障以后线程操作的Connection都为同一个 ThreadLocal.set会在thread中ThreadLocalMap保留值,以ThreadLocal为键,value为值 ThreadLocal.get会获取thread中的ThreadLocalMap以ThreadLocal取值 ThreadLocalMap是ThreadLocal的外部类,被thread援用
五、Java中的锁
1、Lock接口 非阻塞获取锁、超时获取锁、响应中断的获取锁 2、AQS 1定义同步组件,实现AQS,重写相应办法,同步组件调用AQS的模板办法即可 2依赖同步队列实现同步状态的治理 同步队列中有节点保留获取同步线程失败的线程援用,期待状态 同步器蕴含头尾节点,首节点是获取同步状态胜利的节点,开释同步状态时唤醒后继节点并设置为首节点 3、重入锁:反复加锁而不被本人阻塞 ReentrantLock|Synchronized 偏心与非偏心锁:是否申请程序 ReentrantLock 4、读写锁ReentrantReadWriteLock 一个读多个写 保护一对读锁写锁 同步整型状态按位切割 锁降级(写->读) 5、LockSupport工具 阻塞唤醒以后线程 6、Condition(Lock.newCondition) 相似wait/notify 作为同步器的外部类,AQS援用多个Condition期待队列 await同步队列首节点->期待队列尾结点 signal期待队列首节点->同步队列首节点
六、Java并发容器和框架
1、ConcurrentHashMap JDK7 segment[](继承自ReentantLockd)->数组+链表 get不加锁(volatile润饰) put加分段锁(判断是否扩容,单个Segment扩容) JDK8 数组+链表+红黑树 get不加锁 put时初始化,没有hash抵触间接CAS插入,有就synchronized锁住头结点插入 put操作 1数组为空则进行初始化 2首节点为空则cas直接插入 3须要扩容则帮助扩容 扩容时多线程并发扩容helpTransfer 非凡首节点ForwardingNode示意已扩容过间接跳过 4首节点加synchronized锁put 2、线程平安队列 非阻塞(循环cas)|阻塞(锁) 3、ConcurrentLinkedQueue无界限程平安队列 cas入队尾结点 cas出队列头结点 4、阻塞队列BlockingQueue ArrayBlockingQueue 数组构造的有界阻塞队列(必须指定长度) 不保障偏心拜访 LinkedBlockingQueue 链表构造的有界阻塞队列(可指定,默认长度为int_max) PriorityBlockingQueue 反对优先级的无界阻塞队列(可扩容,长度最大也为int_max(queue为数组实现的堆)) DelayQueue 延时获取元素的无界阻塞队列 SynchronnousQueue 一个put对应一个take不存储元素 LinkedTransferQueue 链表构造的无界阻塞队列 LinkedBlockingQueue 链表构造组成的双向阻塞队列 阻塞队列实现原理 期待告诉模式 condition.await|signal->LockSupport.park|unpark(先保留以后线程再阻塞)->底层park|unpark
七、原子操作类
原子更新根本类型 AtomicBoolean AtomicInteger AtomicLong(其余根本类型 转为int型) 以AtomicInteger的getAndIncrement为例 get()获取旧值 新值=旧值+1 cas(旧值,新值)->unsafe的native办法 循环直到胜利 原子更新数组 AtomicIntegerArray AtomicLongArray AtomicReferenceArray 原子更新援用类型 AtomicReference AtomicReferenceFiledUpdatr AtomicMarkableReference 原子更新字段类 AtomicIntegerFiledUpdater AtomicLongFiledUpdater AtomicStampedReference
八、Java中的并发工具类
1、CountDownLatch代替join实现计数器 2、CyclicBarrier 阻塞一批线程直到所有线程都实现,关上屏障 下一步动作实施者不一样CountdownLatch为主线程 CyclicBarrier为其余线程 CyclicBarrier 计数器能够重置 适宜更简单场景 3、Semaphore 管制并发线程的数量 流控 4、Exchanger 线程间替换数据
九、线程池
1、实现原理 execute提交工作 外围线程池未满(即便有闲暇,不销毁)则创立线程执行工作,已满则阻塞队列是否已满,未满则退出队列,已满则看线程池是否已满,未满则创立线程执行工作,已满则执行回绝策略 创立的线程封装为工作线程Worker,执行完从阻塞队列中获取工作 2、new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue,threadFactory,handler) corePoolSize 外围线程大小 maximumPoolSize 最大线程数量 keepAliveTime 闲暇线程存活工夫 workQueue ArrayBlockingQueue LinkedBlockingQuene SynchronousQuene PriorityBlockingQueue threadFactory 线程工厂 次要定义名字 handler 回绝策略 CallerRunsPolicy 调用者线程执行 AbortPolicy 间接抛弃 抛出RejectedExecutionException异样 DiscardPolicy 间接抛弃 DiscardOldestPolicy 摈弃最早进入队列的工作,放进队列 3、Executor框架 ThreadPoolExecutor SingleThreadExecutor 1-1 LinkedBlockingQueue FixedThreadPool core-max LinkedBlockingQueue CacheThreadPool 0-max SynchronousQueue 不同创立线程 ScheduledThreadPoolExecutor 比Timer更灵便 ScheduledThreadPoolExecutor DelayQueue 外部是一个PriorityQueue把time小的优先 工作须要实现Delay接口 SingleThreadScheduledExecutor Future 示意后果 Runnable Callable Executors
总结
最近,没那么多工夫来写博客了,只能简略的对重读的常识,进行总结,所以排版不是很好,有工夫会回来优化的!