参考文章
https://zhuanlan.zhihu.com/p/164532324
这21 个刁钻的HashMap 面试题,我把阿里面试官吊打了!
https://zhuanlan.zhihu.com/p/471500229
Java代码是要运行在虚拟机上的,而虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途。
JVM的内存结构的图中,我们可以看到,其中Java堆和方法区的区域是多个线程共享的数据区域。也就是说,多个线程可能可以操作保存在堆或者方法区中的同一个数据。这也就是我们常说的“Java的线程间通过共享内存进行通信”。
Java内存模型是根据英文Java Memory Model(JMM)翻译过来的。其实JMM并不像JVM内存结构一样是真实存在的。他只是一个抽象的概念。JSR-133: Java Memory Model and Thread Specification中描述了,JMM是和多线程相关的,他描述了一组规则或规范,这个规范定义了一个线程对共享变量的写入时对另一个线程是可见的。
那么,简单总结下,Java的多线程之间是通过共享内存进行通信的,而由于采用共享内存进行通信,在通信过程中会存在一系列如可见性、原子性、顺序性等问题,而JMM就是围绕着多线程通信以及与其相关的一系列特性而建立的模型。JMM定义了一些语法集,这些语法集映射到Java语言中就是volatile、synchronized等关键字。
Java是一种面向对象的语言,而Java对象在JVM中的存储也是有一定的结构的。而这个关于Java对象自身的存储模型称之为Java对象模型。
HotSpot虚拟机中,设计了一个OOP-Klass Model。OOP(Ordinary Object Pointer)指的是普通对象指针,而Klass用来描述对象实例的具体类型。
JVM内存结构,和Java虚拟机的运行时区域有关。
Java内存模型,和Java的并发编程有关。
Java对象模型,和Java对象在虚拟机中的表现形式有关。
JVM内存结构 VS Java内存模型 VS Java对象模型
再有人问你Java内存模型是什么,就把这篇文章发给他。
深入理解多线程(一)——Synchronized的实现原理
对JVM内存结构的描述中,我们知道了堆和方法区是线程共享的。而局部变量,方法定义参数和异常处理器参数就不会在线程之间共享,它们不会有内存可见性问题,
也不受内存模型的影响。
Java线程之间的通信由Java内存模型(本文简称为JMM)控制,JMM决定一个线程对共享变量的写入何时对另一个线程可见。
从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),
本地内存中存储了该线程以读/写共享变量的副本。本地内存是JMM的一个抽象概念,并不真实存在。
它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。
AtomicInteger是一个提供原子操作的Integer类,通过线程安全的方式操作加减。
AtomicInteger提供原子操作来进行Integer的使用,因此十分适合高并发情况下的使用。
1.作为多个线程同时使用的原子计数器。
2.在比较和交换操作中实现非阻塞算法。
要将其用作计数器,AtomicInteger类提供了一些方法来原子地执行加减运算。
1 | addAndGet():以原子方式将给定值添加到当前值,并在添加后返回新值。 |
JVM——1. 运行时数据区域
JVM——2. 对象及内存分配策略与分代
JVM——3. 垃圾回收算法
JVM——4. 常用垃圾收集器
JVM——5.性能优化
JVM——6.GC日志分析1(模拟对象进入老年代)
JVM——7.GC日志分析2(老年代GC)
JVM——8.调优工具1(jstat)
值传递概念:
值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
引用传递:
所谓引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。
1 | import java.io.BufferedReader; |
1 | import java.io.BufferedReader; |
-
method | 什么类的方法 | 描述 |
---|---|---|
wait() notify() notifyAll() | Object的本地final方法,无法被重写 | 实现线程间的通信 在线程中调用 wait() 方法,将阻塞当前线程,直至等到其他线程调用了调用 notify() 方法或 notifyAll() 方法进行通知之后,当前线程才能从 wait() 方法出返回,继续执行下面的操作。 |
park() unpark() | 工具类LockSupport | 1.park和unpark是以线程为单位精确阻塞和唤醒线程的; 2.阻塞和唤醒的先后执行顺序可以不一样; |
await和signal | Condition | Object的wait和notify/notify是与对象监视器配合完成线程间的等待/通知机制,而Condition与Lock配合完成等待通知机制,前者是java底层级别的,后者是语言级别的,具备更高的可控制性和扩展性 |
join() | thread | 控制线程执行顺序 |