HashMap源码详解
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220 ...
守护线程与用户线程
守护线程与用户线程 用户线程:我们平常创建的普通线程。
守护线程:用来服务于用户线程;不需要上层逻辑介入
java线程分为守护线程和非守护线程,当java jvm检测主线程或其他子线程执行完之后,守护线程也会马上停止执行,我们可以使用Thread.setDaemon(ture或false)来设置一个线程是守护线程还是非守护线程,默认为false,可以通过Thread.isDaemon()方法查询该线程是否是守护线程
1:我们将用案例来告诉你守护线程和非守护线程的区别和用法,代码如下,先设置其为守护线程。
123456789101112131415161718192021public class DeamonThread { public static void main(String[] args) { //"DeamonThread::print"是java1.8调用静态方法 Thread thread = new Thread(DeamonThread::print); ...
java中的ThreadPoolExecutor
java中的ThreadPoolExecutor1. 为什么要使用线程池
降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。
提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。但是要做到合理的利用线程池,必须对其原理了如指掌。
2. ThreadPoolExecutor中的构造器
1234567public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ...
ThreadLocal
java中的ThreadLocal1. ThreadLocal的作用:
ThreadLocal的作用主要是做数据隔离,填充的数据只属于当前线程,变量的数据对别的线程而言是相对隔离的,在多线程环境下,如何防止自己的变量被其它线程篡改。
2. ThreadLocal使用到的场景:
Spring采用Threadlocal的方式,来保证单个线程中的数据库操作使用的是同一个数据库连接,同时,采用这种方式可以使业务层使用事务时不需要感知并管理connection对象,通过传播级别,巧妙地管理多个事务配置之间的切换,挂起和恢复。
3. ThreadLocal的原理:
其实使用真的很简单,线程进来之后初始化一个可以泛型的ThreadLocal对象,之后这个线程只要在remove之前去get,都能拿到之前set的值,注意这里我说的是remove之前。
他是能做到线程间数据隔离的,所以别的线程使用get()方法是没办法拿到其他线程的值的
以下是set时的源码
1234ThreadLocal<String> localName = new ThreadLocal();localName. ...
java 中的四大引用
java 中的四大引用1. 强引用:(StrongReference)
强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。 ps:强引用其实也就是我们平时A a = new A()这个意思。
2. 软引用(SoftReference)
如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存(下文给出示例)。软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。String str = new String("abc"); SoftReference<String> softReference = new SoftReference&l ...
ConcurrentHashMap 详解
ConcurrentHashMap 详解private static final int MAXIMUM_CAPACITY = 1 << 30;
MAXIMUM_CAPACITY是2的30次方 的原因`
int的最大的值是2的31次方-1,所以容量无法到达2的31次方,
需要让容量满足2的幂次,所以设置为2的30次方
private static final int DEFAULT_CAPACITY = 16;
DEFAULT_CAPACITY = 16;
方便数据迁移
方便进行计算对应的位置
概率统计
new ConcurrentHashMap<>(2); 自定义大小解释:12345678public ConcurrentHashMap(int initialCapacity) { if (initialCapacity < 0) throw new IllegalArgumentException(); int cap = ((initialCapacity >= (MAXIMUM_CAPACIT ...
Java 中的并发
java 中的Lock
ReentrantLock
ReentrantReadWriteLock
ReentrantLock
lock
java 中的并发容器
ConcurrentHashMap:并发版 HashMap
CopyOnWriteArrayList:并发版 ArrayList
CopyOnWriteArraySet:并发 Set
ConcurrentLinkedQueue:并发队列 (基于链表)
ConcurrentLinkedDeque:并发队列 (基于双向链表)
ConcurrentSkipListMap:基于跳表的并发 Map
ConcurrentSkipListSet:基于跳表的并发 Set
ArrayBlockingQueue:阻塞队列 (基于数组)
LinkedBlockingQueue:阻塞队列 (基于链表)
LinkedBlockingDeque:阻塞队列 (基于双向链表)
PriorityBlockingQueue:线程安全的优先队列
SynchronousQueue:读写成对的队列
LinkedTransferQueue:基于链表的数据交换队列
Del ...
synchronized
synchronized
jdk早期的synchronized为什么是重量级的
因为我们的jvm是运行在操作系统上的,即用户态,而我们的操作系统是运行在内核态的,用户态中的程序是不能直接调用系统指令的,所以synchronized必须经过老大操作系统,所以synchronized是重量级锁
synchronized的升级过程
偏向锁:
引入偏向锁是为了在无多线程竞争的情况下尽量减少不必要的轻量级锁执行路径,因为轻量级锁的获取及释放依赖多次CAS原子指令,而偏向锁只需要在置换ThreadID的时候依赖一次CAS原子指令(由于一旦出现多线程竞争的情况就必须撤销偏向锁,所以偏向锁的撤销操作的性能损耗必须小于节省下来的CAS原子指令的性能消耗)。上面说过,轻量级锁是为了在线程交替执行同步块时提高性能,而偏向锁则是在只有一个线程执行同步块时进一步提高性能。
偏向锁的获取:
(1)访问Mark Word中偏向锁的标识是否设置成1,锁标志位是否为01——确认为可偏向状态。
(2)当第一次第一个线程来的时候将Mark Word中线程ID设置为当前线程ID
偏向锁的释放
偏向锁只有遇到其他 ...
volatile
volatile的用途问题: DCL单例需不需要加volatile?123456789101112131415161718class Instance { //此处加volatile 和 不加的区别 private volatile static Instance ins = null; private Instance() { } public static Instance getInstance() { if (ins == null) { synchronized (Instance.class) { if (ins == null) { ins = new Instance(); } } } return ins; }}
1.防止指令重排序 ...
java对象结构
java对象结构
HotSpot虚拟机 markOop.cpp 中的 C++ 代码注释片段,描述了 64bits 下 mark-word 的存储状态,也就是如上图结构示意。
markOop.cpp 源码地址: jdk8/hotspot/file/vm/oops/markOop.hpp
HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。
mark-word:对象标记字段占4个字节,用于存储一些列的标记位,比如:哈希值、轻量级锁的标记位,偏向锁标记位、分代年龄等。
Klass Pointer:Class对象的类型指针,Jdk1.8默认开启指针压缩后为4字节,关闭指针压缩(-XX:-UseCompressedOops)后,长度为8字节。其指向的位置是对象对应的Class对象(其对应的元数据对象)的内存地址。
对象实际数据:包括对象的所有成员变量,大小由各个成员变量决定,比如:byte占1个字节8比特位、int占4个字节32比特位。
对齐:最后这段空间补全并非必须,仅仅为了起到占位符的作 ...