本地线程

JVM那些事儿之内存区域

孤者浪人 提交于 2019-12-05 09:16:11
相信绝大多数java开发者或多或少的都应该知道jvm,但是有多少人又深入去了解过,笔者深感自身能力的不足,去看了些资料,觉得还是有必要整理下自己的学习记录,时常回头看看,多看多实践提升自己的能力,故开始进行jvm相关的知识梳理和记录,一起来学习吧 前言 从我们刚开始学习java时,我们就被告知其“一次编写,到处运行”的特点,随着学习和工作的深入,你也应该了解了构成这种特点的原因,说到这里,有点像中间件的思想,有人说过,没什么东西是不能通过添加一个中间件来完成的,如果一个不行,那就两个。 由于jvm的存在,使得java语言可以不去关注系统区别而进行同一套代码的开发,借助class字节码文件在jvm上运行,只需要jvm关注底层系统即可,有没有点像中间件的思想,将底层处理相关部分抽离出来构成jvm,而开发者无需关注底层实现,根据自己的需要进行自己的开发即可 但是同时由于jvm的存在屏蔽了许多的底层细节,方便了开发人员,但是其缺点也是很明显的,在我们需要对程序进行优化,比如内存,CPU,并发量,IO等进行必要的处理时,就有点懵逼,你是不是经历过下面的场景: 程序内存占用满了,导致程序经常宕机需要重启,不知道从哪里查问题,怎么优化? 程序偶尔莫名其妙的卡顿,代码检查了一遍又一遍,没问题,不知道接下来怎么搞了? 服务器上资源紧张,需要优化配置,怎么做? ... 其他更加离奇的现象就不列举了

多线程编程1.0——基础相关认识

社会主义新天地 提交于 2019-12-05 09:02:14
多线程编程的基础相关认识 基本概念 进程 一个正在执行的程序,程序运行时系统会创建一个正在执行的程序,程序运行时,系统会创建一个进程,并且给每个进程分配独立的内存地址空间保证每个进程地址不会相互干扰。同时,在cup对进程做时间片的切换时,保证进程切换过程中仍然做进程切换之时运行的位置开始执行。所以进程通常还会包含 程序计数器 、堆栈指针。 线程 是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在Unix System V及SunOS中也被称为轻量进程(lightweight processes),但轻量进程更多指内核线程(kernel thread),而把用户线程(user thread)称为线程。 并行 从宏观与微观角度都是有多个执行者同时执行 并发 多个任务被执行,但执行者只有一个,因为执行的速度与切换任务执行的速度非常快,所以在宏观角度上看上去像同时执行的效果。 程序计数器 在程序执行时,程序计数器会实时,记录当前执行到的行数 java中实现多线程的方式 继承Thread类 继承Thread类,重写run方法,在需要开辟新线程的地方实例化这个继承了Thread类的类,调用start()方法,即可启动一个新的线程。 补充:start(

高精尖面试题(一)

你离开我真会死。 提交于 2019-12-05 06:18:11
jdk jre jvm 三者的区别 JVM :英文名称(Java Virtual Machine),就是我们耳熟能详的 Java 虚拟机。它只认识 xxx.class 这种类型的文件,它能够将 class 文件中的字节码指令进行识别并调用操作系统向上的 API 完成动作。所以说,jvm 是 Java 能够跨平台的核心,具体的下文会详细说明。 JRE :英文名称(Java Runtime Environment),我们叫它:Java 运行时环境。它主要包含两个部分,jvm 的标准实现和 Java 的一些基本类库。它相对于 jvm 来说,多出来的是一部分的 Java 类库。 JDK :英文名称(Java Development Kit),Java 开发工具包。jdk 是整个 Java 开发的核心,它集成了 jre 和一些好用的小工具。例如:javac.exe,java.exe,jar.exe 等。 显然,这三者的关系是:一层层的嵌套关系。 JDK>JRE>JVM 。 HDFS的副本数为什么为3,为什么不是2或者是4? HDFS的副本数默认是3,并不是必须是3. 修改hdfs的副本数,首先想到的是修改hdfs-site.xml中的dfs.replication参数 HDFS采用一种称为机架感知的策略来改进数据的可靠性、可用性和网络带宽的利用率。 在大多数情况下,HDFS的副本系数是3

ThreadLocal

一笑奈何 提交于 2019-12-05 05:14:26
ThreadLocal,线程变量,是一个以ThreadLocal对象为键、任意对象为值的存储结构。这 个结构被附带在线程上,可以通过set(T)方法来设置一个值,在当前线程下再通过get()方法获取到原先设置的值 ThreadLocal是保存线程本地化对象的容器。当运行于多线程环境的某个对象使用ThreadLocal维护变量时,ThredLocal为每个使用该变量的线程分配一个独立的变量副本。所以每个线程都可以独立地改变自己的副本,而不会影响到其他线程所对应的副本 InheritableThreadLocal继承于ThreadLocal,它自动为子线程复制一份从父线程那里继承而来的本地变量:在创建子线程时,子线程会接收所有可继承的线程本地变量的初始值。当必须将本地线程变量自动传给所有创建的子线程时,应尽可能使用InheritableThreadLocal 在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序缜密地分析什么时候对变量进行读写、什么时候需要锁定某个对象、什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大; 而ThreadLocal从另一个角度来解决多线程的并发访问。ThreadLocal为每个线程提供了一个独立的变量副本,从而隔离了多个线程对数据访问的冲突。因为每个线程都拥有自己的变量副本

分析线程并发访问代码解释原因

只谈情不闲聊 提交于 2019-12-05 02:43:00
class ConcurrentThread { /** * 分析线程并发访问代码解释原因 * volatile关键字: * 1):保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的 * 2):禁止进行指令重排序 * volatile本质是告诉JVM当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取 */ private volatile int count = 0; public void inc() { try { Thread.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } count++; } @Override public String toString() { return "[count=" + count + "]"; } } //---------------------------------------- public class VolatileTest { public static void main(String[] args) { final ConcurrentThread counter = new ConcurrentThread(); for (int i = 0; i < 1000;

Java多线程面试题

醉酒当歌 提交于 2019-12-05 02:22:31
   1、启动一个线程是调用run()方法还是start()方法?      启动一个线程是调用start()方法,是线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行,这并不意味着线程就会立即执行   2、请说出同步线程及线程调度相关的方法?     wait():是一个线程等待(阻塞bolcked)状态,并且释放所持有的对象的锁     sleep():是一个正在运行状态的线程处于睡眠状态,是一个静态方法,调用此方法要处理InterruptedException异常;     notify():唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一等待状态的线程,而是由JVM确定唤醒哪个线程,而且与优先级无关。     notifyAll():唤醒所有处于等待状态的线程,该方法并不是将对象的锁给所有线程,而是让它们竞争,只有获得了锁的线程才能进入就绪状态。     注意:Java5通过Lock接口提供了 显式的锁机制 ,Lock接口中定义了加锁(lock()方法)和解锁(unlock()方法),增强了多线程编程的灵活性及对线程的协调。???    3、线程和进程的区别?     进程:具有一定独立功能的程序关于某个数据集合上的一次运行活动,是操作系统进行资源分配和调度的一个独立单位。     线程:是进程的一个实体

JVM——内存结构

。_饼干妹妹 提交于 2019-12-04 23:33:26
一、程序计数器/PC寄存器 ( Program Counter Registe )   用于 保存当前正在执行的程序的内存地址(下一条jvm指令的执行地址) ,由于Java是支持多线程执行的,所以程序执行的轨迹不可能一直都是线性执行。当有多个线程交叉执行时,被中断的线程的程序当前执行到哪条内存地址必然要保存下来,以便用于被中断的线程恢复执行时再按照被中断时的指令地址继续执行下去。为了线程切换后能恢复到正确的执行位置, 每个线程都需要有一个独立的程序计数器 ,各个线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存,是线程安全的。    特点: 1.线程私有 2.不会存在内存溢出 二、虚拟机栈(Java Virtual Machine Stack)    虚拟机栈总是与线程关联在一起的, 每当创建一个线程,JVM就会为该线程创建对应的虚拟机栈 ,在这个 虚拟机栈中又会包含多个栈帧(Stack Frame) ,这些栈帧是与每个方法关联起来的, 每运行一个方法就创建一个栈帧 ,每个栈帧会含有一些局部变量、操作栈和方法返回值等信息。每当一个方法执行完成时,该栈帧就会弹出栈帧的元素作为这个方法的返回值,并且清除这个栈帧, 虚拟机栈的栈顶的栈帧就是当前正在执行的活动栈,也就是当前正在执行的方法,PC寄存器也会指向该地址。(只有一个活动栈)

多线程之美1一volatile

假装没事ソ 提交于 2019-12-04 21:12:28
摘自: https://www.cnblogs.com/flydashpig/p/11875652.html 多线程之美1一volatile 目录 一、java内存模型 1.1、抽象结构图 1.2、概念介绍 二、volatile详解 2.1、概念 2.2、保证内存可见性 2.3、不保证原子性 2.4、有序性 一、java内存模型 1.1、抽象结构图 1.2、概念介绍 java 内存模型 即Java memory model(简称JMM), java线程之间的通信由JMM控制,决定一个线程对共享变量的写入何时对另一个线程可见。 多线程通信通常分为2类:共享内存和消息传递 JMM采用的就是共享内存来实现线程间的通信,且通信是隐式的,对程序开发人员是透明的,所以在了解其原理了,才会对线程之间通信,同步,内存可见性问题有进一步认识,避免开发中出错。 线程之间如何通信? 在java中多个线程之间要想通信,如上图所示,每个线程在需要操作某个共享变量时,会将该主内存中这个共享变量拷贝一份副本存在在自己的本地内存(也叫工作内存,这里只是JMM的一个抽象概念,即将其笼统看做一片内存区域,用于每个线程存放变量,实际涉及到缓存,寄存器和其他硬件),线程操作这个副本,比如 int i = 1;一个线程想要进行 i++操作,会先将变量 i =1 的值先拷贝到自己本地内存操作,完成 i++,结果 i=2

还没搞懂JVM吗?95%的技术面试必问知识点都在这,还怕面不过?

与世无争的帅哥 提交于 2019-12-04 20:42:28
概述:知识点汇总 jvm的知识点汇总共6个大方向:内存模型、类加载机制、GC垃圾回收是比较重点的内容。性能调优部分偏重实际应用,重点突出实践能力。编译器优化和执行模式部分偏重理论基础,主要掌握知识点。 各个部分的内容如下: 1>内存模型部分 :程序计数器、方法区、堆、栈、本地方法栈的作用,保存哪些数据; 2>类加载部分 :双亲委派的加载机制以及常用类加载器分别加载哪种类型的类; 3>GC部分 :分代回收的思想和依据,以及不同垃圾回收算法实现的思路、适合的场景; 4>性能调优部分 :常用的jvm优化参数的作用,参数调优的依据,要了解常用的jvm分析工具能分析哪类问题,以及使用方法; 5>执行模式部分 :解释、编译、混合模式的优缺点,了解java7提供的分层编译技术。需要知道JIT即时编译技术和OSR也就是栈上替换,知道C1、C2编译器针对的场景,其中C2针对server模式,优化更激进。在新技术方面可以了解一下java10提供的由java实现的graal编译器。 6>编译优化部分 :前端编译器javac的编译过程、AST抽象语法树、编译期优化和运行期优化。编译优化的常用技术,包括公共子表达式的消除、方法内联、逃逸分析、栈上分配、同步消除等。明白了这些才能写出对编译器友好的代码。 jvm的内容相对来说比较集中,但是对知识深度的掌握要求较高,建议面试前重点加强。 一、jvm内存相关考点

java多线程面试题总结(转载)

丶灬走出姿态 提交于 2019-12-04 19:43:27
文章转载自 40个Java多线程问题总结 ####40个问题汇总结 #####多线程有什么用 发挥多核CPU的优势 随着工业的进步,现在的笔记本、台式机乃至商用的应用服务器至少也都是双核的,4核、8核甚至16核的也都不少见,如果是单线程的程序,那么在双核CPU上就浪费了50%,在4核CPU上就浪费了75%。单核CPU上所谓的"多线程"那是假的多线程,同一时间处理器只会处理一段逻辑,只不过线程之间切换得比较快,看着像多个线程"同时"运行罢了。多核CPU上的多线程才是真正的多线程,它能让你的多段逻辑同时工作,多线程,可以真正发挥出多核CPU的优势来,达到充分利用CPU的目的。 防止阻塞 从程序运行效率的角度来看,单核CPU不但不会发挥出多线程的优势,反而会因为在单核CPU上运行多线程导致线程上下文的切换,而降低程序整体的效率。但是单核CPU我们还是要应用多线程,就是为了防止阻塞。试想,如果单核CPU使用单线程,那么只要这个线程阻塞了,比方说远程读取某个数据吧,对端迟迟未返回又没有设置超时时间,那么你的整个程序在数据返回回来之前就停止运行了。多线程可以防止这个问题,多条线程同时运行,哪怕一条线程的代码执行读取数据阻塞,也不会影响其它任务的执行。 便于建模 这是另外一个没有这么明显的优点了。假设有一个大的任务A,单线程编程,那么就要考虑很多,建立整个程序模型比较麻烦