Java集合:
Java集合:
Connection顶级接口
{
List接口
ArrayList:动态扩容数组 第一次put()时,才初始化:10 扩容后1.5倍 查询快,一次读取连续数组到cpu内存。一次用户态和核心态的切换。
LinkedList:双向链表,头插和尾插都可添加 ,添加、删除快-分拆链表代价小于数组复制。 有序
Vector:动态扩容数组+synchronized (线程安全)初始化:10 扩容后2倍
Set接口
HashSet 初始化:16 扩容后2倍 底层调用HashMap的key实现 无序
TreeSet 有序的
LinkedHashSet 有序的 插入顺序
}
Map接口:
HashMap 初始化:16 扩容后2倍 负载因子0.75 JDK 1.6 数组加单向链表解决Hash冲突(拉链法、再Hash、扩展表、寻址法),头插法,扩容再hASH会导致回环,1.7 数组+链表+红黑书 链表长度大于8,总元素大于64,小于6变为链表,尾插法,改进渐进式Hash(redis)(红黑树可以用跳跃表)
HashTable 初始化:11 扩容后2倍+1 + synchronized 底层调用HashMap实现。 无序,HashTable(key value) 都不为空(无法判断存的是null,还是没有映射操作过),hashMap相反,hashMap做了特殊处理,第一个槽位专门存key为空的键值对。
线程安全的类:Vector、HashTable 、StringBuffer
Java锁
synchronized与Lock
synchronized
锁原理:synchronized完成后强制刷新回主存 volication
开始是无锁状态,有工作线程进入带锁的区域,升级为偏向锁,把线程 ThreadID 存入对象头的Mark world 的一个位置,如果为null,则存入,该线程再次访问,与对象头比较相同则直接进入,上个线程结束后,把mark world thradID 置空(锁消除),非同一线程访问,到全局安全点,多次eplod到40,升级为轻量级锁,把mark world 拷贝一份存入线程栈帧,lock Record 锁记录,用cas,尝试把线程指针写入mark world 成功 获取轻量级锁,失败CAS自旋10次(自适应自旋),失败升级重量级锁,先加上moinitorenter和monitorexit,锁对象关联一个monitor监视器锁,把线程id存储到monitor监视器锁中,重入monitor 监视器锁的jsoure++,失败的加入_cxq队列中,下次竞争失败加入entity队列中,调用wait方法,放入wait队列。
锁升级、
(静态同步方法{锁类}、普通方法上{锁对象}:ACC_SYNCHRONIZED 隐式带调用
换锁过程:编译后monitorenter monitorexit,加开始是无锁状态mark world 锁状态是01,关联监视器锁 monitor对象,把ThreadID写入,monitor 计数器(+1)把monitor指针写入mark world,修改锁对象为10,完成换锁。
代码块{锁对象or锁类}):monitorenter monitorexit 程序计数器 +1
Lock CAS自旋cpu开销(限制重试次数)--轻量级锁、一个共享标量加锁、ABA问题(versionCode)
Lock与synchronized区别
Lock JDK层面,synchronized JVM层面
lock需要手动释放锁、synchronized自动释放或异常释放
lock可以打断,synchronized不可打断
lock丰富的API方法(高级特性)synchronized没有
lock可以交互加锁,A加锁成功B才能加锁,然后A才能释放,B才能释放,synchronized不能
lock适合低并发,synchronized锁升级(无法降级,偏向锁的锁消除oples,大量轻量级锁自旋)
lock只能锁代码块,synchronized可以锁方法和代码块
synchronized非公平锁,lock可选择公平or非公平锁
lock有读锁提高效率