前言最近又把《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总结最近,没那么多工夫来写博客了,只能简略的对重读的常识,进行总结,所以排版不是很好,有工夫会回来优化的!
...