一、基础概念

1、重进入

  当一个线程请求已被其他线程占有的锁时,请求线程会被阻塞。

  但当一个线程请求被自己占有的锁时,请求会成功。即可重进入

2、volatile和锁

  锁可以保证可见性和原子性;

  volatile只能保证可见性;

  四大屏障;

3、CAS

3.1 CAS并发原语体现在Java中就是sun.misc.Unsafe类的各个方法。调用Unsafe中的CAS方法,JVM会帮我们实现出CAS汇编指令。这是一种完全依赖于硬件的功能,通过它实现了原子操作。

  由于CAS是一种系统原语,原语的执行必须是连续的,且不允许中断,也就是说CAS是一条CPU的原子指令,不会造成数据不一致的问题。

3.2 原子引用 AtomicReference

 3.3 手写自旋锁

 3.4 CAS缺点

  1、循环时间长开销大

  2、ABA问题----AtomicStampedReference

 4、Monitor

hotspot中,monitor采用ObjectMonitor实现。

每一个对象都天生带着ObjectMonitor,每一个被锁住的对象都会和Monitor关联起来

 5、原子类

1、分类:基本原子类、数组原子类、

引用原子类:AtomicReference,AtomicStampedReference,AtomicMarkableReference

原子更新对象属性:AtomicIntegerFieldUpdater,AtomicLongFieldUpdater,AtomicReferenceFieldUpdater

 

必须使用int类型,否则报错

 

 AtomicReferenceFieldUpdater

 2、LongAdder和LongAccumulator

LongAdder比AtomicLong在大吞吐量时性能显著,减少乐观锁次数;

LongAdder只适用于累加,只能从0开始;

 LongAdder 继承 Striped64 继承 Number

LongAdder总体思想:分散热点,将value值分散到一个Cell数组中,不同线程会命中到数组的不同槽中,各个线程只对自己槽中的值进行CAS操作。如果要获取真正的Long值,只需将各个槽中的值累加返回。

初始化cell数组:

 扩容

 

 6、ThreadLocal

6.1 初步解释

 ThreadLocal提供线程局部变量,这些变量与正常的变量不同,因为每一个线程在访问ThreadLocal实例的时候,都有自己的、独立初始化的变量副本。ThreadLocal实例通常是类中的私有静态字段,使用他的目的是希望将状态与线程关联起来

 6.2 使用注意

使用完成后调用remove(),删除此线程局部变量的当前线程值。

6.3 源码分析

1、Thread,ThreadLocal,ThreadLocalMap的关系

2、get方法

首先获取当前线程的成员变量threadLocals,即一个ThreadLocalMap,若map为null,则进行初始化;

初始化的过程,即创建一个ThreadLocalMap,赋值给当前线程的threadLocals。

 6.4 内存泄漏问题

1、内存泄漏:不再会被使用的对象或变量占用的内存不能被回收

2、强引用(Reference):对于强引用对象,就算出现了OOM,也不会对该对象进行回收

  强引用是我们最常见的普通对象引用。

3、软引用(SoftReference):对于只有软引用的对象,当系统内存充足时不会回收,系统内存不足时会回收。

4、弱引用(WeakReference):对于只有弱引用的对象,只要垃圾回收器一运行,不管jvm的内存是否足够,都会被回收。

5、虚引用(PhantomReference):

  虚引用形同虚设,如果一个对象仅持有虚引用,那么它和没有任何引用一样,在任何时候都可能被回收,不能单独使用也不能通过它访问对象,虚引用必须和引用队列(ReferenceQueue)结合使用。被回收后会放到引用队列中,可以执行后续的操作,如事后清理操作。

  虚引用的主要作用是跟踪对象被垃圾回收的状态,仅仅只是提供了一种确保对象被finalize后,做某些事情的通知机制。get方法总是返回null

6、为什么用弱引用

如上图所示,因ThreadLocalMap中存放的当前ThreadLocal的引用,而ThreadLocalMap是Thread的成员变量,当栈帧中的强引用取消时,弱引用可被回收,可大大减小内存泄漏的防线。

7、总结

 

 7、对象内存布局

1、对象内存布局初识

  对象在堆内存中的存储布局可以划分为三个部分:对象头、实例数据、对齐填充(整体保证大小为8个字节的倍数)

  对象头:对象标记(Mark Word),类元信息(又叫类型指针)

 2、对象头-MarkWord

包含哈希码(如obj.hashcode()),GC标记,GC次数,同步锁标记,偏向锁持有者等,默认存储HashCode,分代年龄和锁标志位等信息。

64位系统中,MarkWord占8字节

3、对象头-类元信息(类型指针)

每次new对象时的模板,指向方法区的类元信息

64位系统中,类元信息占8个字节

4、实例数据

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

 

posted on 2020-06-24 16:54  dysdhd  阅读(104)  评论(0编辑  收藏  举报