juc

JUC AQS ReentrantLock源码分析

一曲冷凌霜 提交于 2019-11-28 10:12:40
  为了了解java并发包下的 ReentrantLock 可重入锁 和 AbstractQueuedSynchronizer 抽象队列同步器,我自己创建了这两个类,改一下类名,把他们的代码贴过来,再删除英文注释,一步步的分析,再贴上自己的中文理解。然后我发现 BacAQS只有940行,BacReentrantLock 只有230行,然后攻克她。Bac 是我起的英文名,高大上的寓意是 大数据BigData ,Ai人工智能,CloudComputing云计算。读音:巴西。不是喜欢足球,是自己胖得像球。。。  直接上代码,后续会慢慢解读,补充中文注释。你也可以按这个方法,一起学习哦。可重入锁: package www.itbac.com; import java.util.Collection; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; //可重入锁 public class BacReentrantLock implements Lock, java.io.Serializable { private static final long serialVersionUID =

JUC

你。 提交于 2019-11-28 06:24:05
JUC 回顾 1 NIO主要内容:Buffer、Channel 2 非阻塞式网络编程 今天任务 1 volatile的使用 2 原子变量和CAS算法 3 Lock接口 4 并发集合 5 同步工具类 第一节 JUC 概述 在 Java 5.0 提供了 java.util.concurrent(简称JUC)包,在此包中增加了在并发编程中很常用的工具类, 用于定义类似于线程的自定义子系统,包括线程池,异步IO和轻量级任务框架;还提供了用于多线程上下文中的 Collection实现等。 第二节 volatile volatile:易变的,不稳定的 在并发编程中的三个特性: (1)互斥性(原子性) (2)内存可见性 (3)指令重排序 int b=20; int a=10; int c=a+b; volatile 关键字: 当多个线程进行操作共享数据时,可以保证内存中的数据是可见的;相较于 synchronized 是一种较为轻量级的同步策略; volatile 不具备"互斥性"; volatile 不能保证变量的"原子性"; synchronized和volatile的区别: (1)synchronized可以实现互斥性和内存可见性,不能禁止指令重排序。 (2)volatile可以实现内存可见性,禁止指令重排序,不能保证原子性。 案例演示:内存可见性 public class

独享锁/共享锁

你说的曾经没有我的故事 提交于 2019-11-28 05:54:44
原创转载请注明出处: https://www.cnblogs.com/agilestyle/p/11395763.html 独享锁 独享锁:该锁每一次只能被一个线程所持有,参考synchronized以及JUC包下的ReentrantLock 共享锁 共享锁:该锁可被多个线程共有,典型的就是ReentrantReadWriteLock里的读锁,它的读锁是可以被共享的,但是它的写锁每次只能被读占,读锁的共享可保证并发读是非常高效的,但是读写和写写,写读都是互斥的,参考JUC包下的ReentrantReadWriteLock 独享锁和共享锁都是通过AQS队列来实现的,通过实现不同的方法,来实现独享或者共享。 来源: https://www.cnblogs.com/agilestyle/p/11395763.html

java并发系列 - 第28天:实战篇,微服务日志的伤痛,一并帮你解决掉

大城市里の小女人 提交于 2019-11-27 21:24:07
这是java高并发系列第28篇文章。 环境:jdk1.8。 本文内容 日志有什么用? 日志存在的痛点? 构建日志系统 日志有什么用? 系统出现故障的时候,可以通过日志信息快速定位问题,修复bug,恢复业务 提取有用数据,做数据分析使用 本文主要讨论通过日志来快速定位并解决问题。 日志存在的痛点 先介绍一下多数公司采用的方式:目前比较流行的是采用springcloud(或者dubbo)做微服务,按照业拆分为多个独立的服务,服务采用集群的方式部署在不同的机器上,当一个请求过来的时候,可能会调用到很多服务进行处理,springcloud一般采用logback(或者log4j)输出日志到文件中。当系统出问题的时候,按照系统故障的严重程度,严重的会回退版本,然后排查bug,轻的,找运维去线上拉日志,然后排查问题。 这个过程中存在一些问题: 日志文件太大太多,不方便查找 日志分散在不同的机器上,也不方便查找 一个请求可能会调用多个服务,完整的日志难以追踪 系统出现了问题,只能等到用户发现了,自己才知道 本文要解决上面的几个痛点,构建我们的日志系统,达到以下要求: 方便追踪一个请求完整的日志 方便快速检索日志 系统出现问题自动报警,通知相关人员 构建日志系统 按照上面我们定的要求,一个个解决。 方便追踪一个请求完整的日志 当一个请求过来的时候,可能会调用多个服务

JUC 总结

别说谁变了你拦得住时间么 提交于 2019-11-27 18:25:18
1创建线程的方式 比较常见的一个问题了,一般就是四种: (1)继承Thread类 (2)实现Runnable接口 (3)实现 Callable 接口:该方式相较于实现 Runnable 接口,方法多了返回值,并且可以抛出异常 FutureTask (4)线程池 2 start()方法和run()方法的区别 只有调用了start()方法,才会表现出多线程的特性,不同线程的run()方法里面的代码交替执行。如果只是调用run()方法,那么代码还是同步执行的,必须等待一个线程的run()方法里面的代码 全部执行完毕之后,另外一个线程才可以执行其run()方法里面的代码。 3什么是线程安全 如果你的代码在多线程下执行和在单线程下执行永远都能获得一样的结果,那么你的代码就是 线程安全的 。 (1)不可变 像String、Integer、Long这些,都是final类型的类,任何一个线程都改变不了它们的值,要改变除非新创建一个,因此这些不可变对象不需要任何同步手段就可以直接在多线程环境下使用 设置不可变对象的原因: 因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误.此外,由于对象不变,多任务环境下同时读取对象不需要加锁,同时读取数据时不会有任何问题.我们在编写程序时,如果可以设计一个不变对象,那就尽量设计成不变对象. (2)绝对线程安全 不管运行时环境如何

JUC基本使用——并发集合和同步工具类

╄→尐↘猪︶ㄣ 提交于 2019-11-27 16:21:33
并发集合 普通的集合中有List(ArrayList|LinkedList)、Set(HashSet|TreeSet)和Map(HashMap|TreeMap)集合,这些集合只适合在单线程情况下使用。 在Collecionts工具类中有synchronized开头方法可以把单线程集合转成支持并发的集合,但是效率不高,很少使用。 为了更好的实现集合的高并发访问处理,JUC创建了一组新的集合工具类,其使用和一般的集合一样,使用方法参照 “Java之集合” 的分类。 1. List和Set集合 CopyOnWriteArrayList相当于线程安全的ArrayList,实现了List接口,支持高并发 CopyOnWriteArraySet相当于线程安全的HashSet,它继承了AbstractSet类,内部是通过CopyOnWriteArrayList实现的,所以是有序的 set 集合 2.Map集合 ConcurrentHashMap是线程安全的哈希表(相当于线程安全的HashMap);它继承于AbstractMap类,并且实现ConcurrentMap接口。 该集合在jdk1.7之前是采用的分段锁机制,将哈希表分为16段,每段是一个锁,每个段又都是哈希表,写入扩容锁定,读取共享,类似于读写锁机制。 在jdk1.8之后,取消分段锁,改用CAS无锁算法,提高写入小路,另外put方法有锁

JUC锁框架——重入锁ReentrantLock

北城以北 提交于 2019-11-27 16:10:06
重入锁(ReentrantLock)   ReentrantLock是一种可重入的互斥锁,并且加锁是一种显式操作,对逻辑控制的灵活性远远大于synchronized关键字。重入锁是可以完全替代synchronized。并且重入锁的性能是远高于synchronized的,但是jdk6.0开始,jdk对synchronized做了大量的优化,使得两者性能差距不大。另外,ReentrantLock可结合Condition、以及提供了中断响应、锁申请等待限时、公平锁等。 公平锁、非公平锁(ReentrantLock)   ReentrantLock分为“公平锁”和“非公平锁”。它们的区别体现在获取锁的机制上是否公平。在“公平锁”的机制下,线程依次排队获取锁;而“非公平锁”在锁是可获取状态时,不管自己是不是在队列的开头都会获取锁。  运行如下代码,对比公平锁和非公平锁的运行结果 public static void main(String[] args) throws InterruptedException { Lock noFairReentrantLock = new ReentrantLock(); Lock fairReentrantLock = new ReentrantLock(true); Thread[] threads = new Thread[10]; for(int

【JUC源码解析】ForkJoinPool

你说的曾经没有我的故事 提交于 2019-11-27 12:07:38
简介 ForkJoin 框架,另一种风格的线程池(相比于 ThreadPoolExecutor ),采用分治算法,工作密取策略,极大地提高了并行性。对于那种大任务分割小任务的场景(分治)尤其有用。 框架图 几个角色 ForkJoinTask : 有3个实现,分别是RecursiveTask,RecursiveAction,CountedCompleter. RecursiveTask : 可以递归执行的ForkJoinTask。 RecursiveAction : 无返回值的RecursiveTask。 CountedCompleter : 任务执行完成后,触发执行自定义钩子函数。 ForkJoinWorkerThread : 运行 ForkJoinTask 任务的工作线程。 WorkQueue : 任务队列,支持LIFO(last-in-first-out)的push和pop操作(top端),和FIFO(first-in-first-out)的poll操作(base端),队栈二相性。 WorkQueue[] : ForkJoinPool 中的任务分为两种,一种是本地提交的任务Submission task,通过execute()、submit()、invoke()等方法提交的任务;另外一种是工作线程fork出的子任务Worker task.

111 多线程JUC包下代码分析

只愿长相守 提交于 2019-11-27 10:35:04
Java多线程系列目录(共43篇) AtomicLongFieldUpdater:通过反射+CAS实现对传入对象的指定long字段实现类似AtomicLong的操作 http://www.cnblogs.com/skywang12345/p/java_threads_category.html http://blog.csdn.net/bluetjs/article/category/6388965 https://javadoop.com/#concurrency AbstractQueuedSynchronizer(AQS)源码学习笔记 http://www.cnblogs.com/go2sea/p/5618628.html ReentrantLock源码学习笔记 http://www.cnblogs.com/go2sea/p/5627539.html ReentrantReadWriteLock源码学习笔记 http://www.cnblogs.com/go2sea/p/5634701.html http://www.cnblogs.com/haolong/p/6268550.html http://blog.csdn.net/prestigeding/article/details/53286756 http://blog.csdn.net/yanyan19880509

Java多线程系列--“JUC锁”06之 Condition条件

瘦欲@ 提交于 2019-11-27 09:26:55
简介 Condition中的await()方法相当于Object的wait()方法,Condition中的signal()方法相当于Object的notify()方法,Condition中的signalAll()相当于Object的notifyAll()方法。 不同的是,Object中的wait(),notify(),notifyAll()方法是和"同步锁"(synchronized关键字)捆绑使用的;而Condition是需要与"互斥锁"/"共享锁"捆绑使用的。 简单应用: Condition的实现分析 Condition是同步器AbstractQueuedSynchronized的内部类,因为Condition的操作需要获取相关的锁,所以作为同步器的内部类比较合理。每个Condition对象都包含着一个队列(等待队列),该队列是Condition对象实现等待/通知功能的关键。 等待队列: 等待队列是一个FIFO的队列,队列的每一个节点都包含了一个线程引用,该线程就是在Condition对象上等待的线程,如果一个线程调用了await()方法,该线程就会释放锁、构造成节点进入等待队列并进入等待状态。 这里的节点定义也就是AbstractQueuedSynchronizer.Node的定义。 一个Condition包含一个等待队列,Condition拥有首节点(firstWaiter