类的生命周期以及JMM(Java Memory Model)


类的生命周期:类的加载->连接(验证,准备,解析)->初始化->使用->类的卸载
1.类的加载
查找并加载类的二进制数据(class文件)
硬盘上的class文件加载到jvm内存中
2.连接 :验证,准备,解析




jvm结束生命周期的时机:
- 正常结束
- 异常结束/错误
- System.exit()
- 操作系统异常
JVM的内存模型(JAVA Memory Model JMM)
JVM将内存分为两个部分:主内存区和工作内存区

注意:
1.各个线程只能访问自己私有的工作内存(不能访问其它线程的工作内存,也不能访问主内存)
2.不同线程之间,可以通过主内存间接的访问其它线程的工作内存。




Volatile:

重排序:就是把复合动作变成几个原子动作,再对原子动作进行二次排序
比如: int b = 10 ==> int b;b=10两步操作

单例模式(双重检测加锁式)举例:





//volatile 是不能保证原子性和线程安全的 static volatile int num = 0; public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 100; i++) { new Thread(()->{ for(int j = 0;j<3000;j++) { num++; } }).start(); } Thread.sleep(2000);//为了保证下面输出的num 的正确性,因为子线程可能还没跑完 System.out.println(num); //最终的值达不到300000 因为 num++是一个非原子操作 }
使用 java.util.concurrent.atomic 下的 AtomicInteger
package JUC.Atomic; import java.util.concurrent.atomic.AtomicInteger; public class TestAtomic { //volatile 是不能保证原子性和线程安全的 //static volatile int num = 0; static AtomicInteger atomicInt = new AtomicInteger(0); public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 100; i++) { new Thread(()->{ for(int j = 0;j<3000;j++) { atomicInt.incrementAndGet(); } }).start(); } Thread.sleep(2000);//为了保证下面输出的num 的正确性,因为子线程可能还没跑完 System.out.println(atomicInt); } }
JVM运行时的内存区域

程序计数器:





堆:





方法区


常量池:存放编译期间产生的字面量("abc")、符号引用


浙公网安备 33010602011771号