从 Java 代码到 CPU 执行 Java 代码(IDE) javac 命令将源代码编译成 *.class (字节码)文件。 JVM 会根据操作系统和 CPU 平台的差异,将同样的字节码解释成不同的机器指令,无法保证并发安全的效果一致。 CPU 运行机器指令(程序的执行)。 基于并发安全性的考虑,需要制定一套规范、原则,用统一转化过程和结果,保证程序并发执行的安全性。 JVM 内存结构 Java 虚拟机的运行时区域相关。 方法区(Method Area) 是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 堆(heap) Java 堆是线程共享的。在一般情况下,堆可以说是 Java 内存中最大的内存区域。其存放了对象实例,几乎所有的对象实例在这里存储。(这里说是几乎,是因为 JIT 优化的存在,可能会有对象不在堆上分配,而在栈上进行分配)。 Java 虚拟机栈(VM stack) 用于作用于方法执行的一块 Java 内存区域。每个方法在执行的同时都会创建一个栈帧(Stack Framel):用于存储局部变量表、操....
线程未捕获异常应该如何处理? UncaughtException 专门用于处理线程未捕获的异常。能检测出线程未捕获异常而终止的情况。 主线程可以轻松的发现异常,子线程却不行,子线程即使抛出异常,主线程也不受影响。 子线程异常无法用传统方法捕获。 示例:主线程可以轻松的发现异常,子线程却不行,子线程即使抛出异常,主线程也不受影响。 /** * 描述: 单线程,抛出,处理,有异常堆栈 * 多线程,子线程发生异常,会有什么不同? * 子线程抛出异常,主线程并不会中断 * * Exception in thread "Thread-0" java.lang.RuntimeException * at com.xdclass.couponapp.test.uncaughtexception.ExceptionInChildThread.run(ExceptionInChildThread.java:18) * 0 * 1 * 2 */ public class ExceptionInChildThread implements Runnable { public static void m....
线程各属性总览 线程Id、线程名字 线程是从1开始的,除主线程外,JVM虚拟机会开启一些额外的进程:Finalizer、Reference Handler、Signal Dispatcher、Attach Listener /** * 描述: ID从1开始,JVM运行起来后,我们自己创建的线程的ID早已不是2 * * 主线程id 1 * t1的id 20 * t1的名字 Thread-0 * t1的名字 NewThreadT1 */ public class Id { public static void main(String[] args) { Thread t1 = new Thread(); System.out.println("主线程id " + Thread.currentThread().getId()); System.out.println("t1的id " + t1.getId()); System.out.println("t1的名字 " + t1.getName()); //修改t1的名字 t1.setName("NewThreadT1"); System....
Synchronized 简介 同步方法(Synchronized)支持一种简单的策略来防止线程干扰、内存一致性错误:如果一个对象对多个线程可见,则对该对象变量的所有读取或写入都是通过同步方法完成的。 能够保证在同一时刻最多只有一个线程执行同步方法中的代码,以达到保证并发安全的效果。 被 Synchronized 修饰的方法具备原子性 JVM会自动通过 monitor 来加锁和解锁,保证了同一时刻只有一个线程可以执行指定代码,从而保证了线程安全,同时具有可重入和不可中断的性质。 Synchronized 是 Java 的关键字,被 Java 语言原生支持。 是最基本的互斥同步手段 是并发编程中的元老级角色 不使用并发控制的安全隐患 示例:两个线程同时 i++ ,最后结果会比预计的少。 # i++ 原理解析 1. 读取 i 2. i = i +1 3. 将 i 的值写入内存中 package com.xdclass.couponapp.test.SynchronizedDemo; /** * 消失的请求数 * 控制台输出:144313 理想结果应该是 200000 */ p....
UML 特点 统一建模语言(Unified Modeling Language)是一种开发的方法,用于说明、可视化、构建和编写一个正在开发的面向对象的、软件密集系统的制品的开放方法。 UML 展现了一系列最佳工程实践,这些最佳实践在对大规模,复杂系统进行建模方面,特别是在软件架构层次,已经被验证有效。 UML 2.2 分类 UML 2.2 中一共定义了 14 种图示,分类如下: * 结构式图形:强调的是系统式的建模 * 行为式图形:强调系统模型中触发的事件 * 交互式图形:属于行为图形子集合,强调系统模型中资料流程 结构式图形 静态图(类图、对象图、包图) 实现图(组件图、部署图) 剖面图 复合结构图 行为式图形 活动图 状态图 用例图 交互式图形 通信图 交互概述图(UML2.0) 时序图(UML2.0) 时间图(UML2.0) UML 类图 Class Diagram,用于表示类、接口、实例等之间相互的静态关系。虽然名字叫类图,但类图中并不只有类。 第一行 类名(抽象类应该用斜体) 第二行 属性 第三行 方法 + public - private # prot....
方法概览 wait、notify、notifyAll 阻塞阶段 三个方法都属于 Object 类,任何对象都可以调用这三个方法,并且这些方法都是 native final 修饰的,本地方法也不可以被重写。 类似功能 Condition。 wait()只释放其所属的同步代码块使用的锁对象。也就是说只释放当前 monitor 。 &emspl;有时需要一个或多个线程暂时休息一下,等到后续需要它的时候或条件成熟时再去唤醒它。 &emspl;调用 wait 的前提条件是需要获取到 monitor (也就是线程必须已经获取到 synchronized 锁),否则会抛异常 直到以下 4 种情况之一发生时,才会被唤醒 * 另一个线程调用这个对象的 notify() 方法且刚好被唤醒的是本线程。(随机调用一个线程的 notify()方法) * 另一个线程调用这个对象的 notifyAll()方法;(唤醒所有线程), 然后多个被唤醒的线程进行锁的抢占。 * 过了 wait(long timeout) 规定的超时时间会自动唤醒,如果传入 0 就是永久等待。 * 线程自身调用了in....
操作系统、进程、线程之间的关系 操作系统是包含多个进程的容器,而每个进程又都是容纳多个线程的容器。 进程:使用 fork(2) 系统调用创建的 UNIX 环境(比如:文件描述符,用户 ID 等),它被设置为运行程序。 进程就是代码的实例化对象。是资源分配的基本单位。 线程:在进程上下文中执行的一系列指令。 Windows 下查看进程下所有线程 PsList v1.4 * 然后将解压后的 pslist.exe 复制到 C:\Windows\System32 文件夹下 * 执行 PSlist -dmx PID (用来查看指定进程下有哪些线程) * windows10 可以启动 资源监视器 来查看 java.exe进程的线程数 模拟线程 /** * 创建 100 个线程,用任务管理器的CPU栏目看Java线程数量的变化,10秒钟后线消失。 */ public class Create100Threads { public static void main(String[] args) { for (int i = 0; i < 100; i++) { new Thread(n....