目录

Life in Flow

知不知,尚矣;不知知,病矣。
不知不知,殆矣。

标签: Java (110)

Java 内存模型

从 Java 代码到 CPU 执行 Java 代码(IDE) javac 命令将源代码编译成 *.class (字节码)文件。 JVM 会根据操作系统和 CPU 平台的差异,将同样的字节码解释成不同的机器指令,无法保证并发安全的效果一致。 CPU 运行机器指令(程序的执行)。  基于并发安全性的考虑,需要制定一套规范、原则,用统一转化过程和结果,保证程序并发执行的安全性。 JVM 内存结构  Java 虚拟机的运行时区域相关。 方法区(Method Area)  是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 堆(heap)  Java 堆是线程共享的。在一般情况下,堆可以说是 Java 内存中最大的内存区域。其存放了对象实例,几乎所有的对象实例在这里存储。(这里说是几乎,是因为 JIT 优化的存在,可能会有对象不在堆上分配,而在栈上进行分配)。 Java 虚拟机栈(VM stack)  用于作用于方法执行的一块 Java 内存区域。每个方法在执行的同时都会创建一个栈帧(Stack Framel):用于存储局部变量表、操....

线程异常 UncaughtException

线程未捕获异常应该如何处理?  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)支持一种简单的策略来防止线程干扰、内存一致性错误:如果一个对象对多个线程可见,则对该对象变量的所有读取或写入都是通过同步方法完成的。  能够保证在同一时刻最多只有一个线程执行同步方法中的代码,以达到保证并发安全的效果。  被 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....

Thread和Object类中线程相关方法

方法概览 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....

线程生命周期

线程状态转换机 NEW:已经创建但还没启动的新线程。已经做了准备工作,但还没有调用 start()方法。 RUNNABLE:处于可运行状态的线程正在 JVM 中执行,但它可能正在等待来自操作系统的其他资源,例如处理器。 # Java 中的 RUNNABLE 状态对应操作系统中的两种状态 * Ready:等待分配CPU时间片。 * Running:执行中。 BLOCKED:进入 synchronized 修饰的代码块或方法,等待获取 monitor 锁之后进入 RUNNABLE。 WAITING:Object.wait()、join()、 LockSupport.park(),进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。 TIME_WAITING:Object.wait(time)、Thread.join(time)、LockSupport.parkNanos(time)、LockSupport.parkUntil(time),该状态不同于 WAITING,它可以在指定的时间内自行返回。 TERMINATED:表示该线程已经执行完毕。 BLOCKED 与 ....