本地线程

图示JVM工作原理

こ雲淡風輕ζ 提交于 2020-02-28 20:29:32
JDK,JRE,JVM的联系是啥? JVM Java Virtual Machine JDK Java Development Kit JRE Java Runtime Environment 看上图官方的介绍讲的很清楚 JVM的作用是啥? JVM有2个特别有意思的特性,语言无关性和平台无关性。 语言无关性是指实现了Java虚拟机规范的语言对可以在JVM上运行,如Groovy,和在大数据领域比较火的语言Scala,因为JVM最终运行的是class文件,只要最终的class文件复合规范就可以在JVM上运行。 平台无关性是指安装在不同平台的JVM会把class文件解释为本地的机器指令,从而实现Write Once,Run Anywhere JVM运行时数据区 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。Java虚拟机所管理的内存将会包括以下几个运行时数据区域 其中方法区和堆是所有线程共享的数据区 程序计数器,虚拟机栈,本地方法栈是线程隔离的数据区,画一个逻辑图 程序计数器 程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器 为什么要记录当前线程所执行的字节码的行号?直接执行完不就可以了吗?

图示JVM工作原理

房东的猫 提交于 2020-02-28 19:36:29
JDK,JRE,JVM的联系是啥? JVM Java Virtual Machine JDK Java Development Kit JRE Java Runtime Environment 看上图官方的介绍讲的很清楚 JVM的作用是啥? JVM有2个特别有意思的特性,语言无关性和平台无关性。 语言无关性是指实现了Java虚拟机规范的语言对可以在JVM上运行,如Groovy,和在大数据领域比较火的语言Scala,因为JVM最终运行的是class文件,只要最终的class文件复合规范就可以在JVM上运行。 平台无关性是指安装在不同平台的JVM会把class文件解释为本地的机器指令,从而实现Write Once,Run Anywhere JVM运行时数据区 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。Java虚拟机所管理的内存将会包括以下几个运行时数据区域 其中方法区和堆是所有线程共享的数据区 程序计数器,虚拟机栈,本地方法栈是线程隔离的数据区,画一个逻辑图 程序计数器 程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器 为什么要记录当前线程所执行的字节码的行号?直接执行完不就可以了吗?

java锁的内存语义

荒凉一梦 提交于 2020-02-28 18:41:25
锁的获取和释放 线程释放锁时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存中。 线程获取锁时,JMM会把该线程对应的本地内存置为无效。从而使得被监视器保护的临界区代码必须从主内存中读取共享变量。 在共享变量的可见性方面,锁的释放和获取和volatile是类似的。 对volatile变量进行写操作,JMM会把该线程对应的本地内存中的共享变量刷新到主内存中。 对volatile变量进行读操作,JMM会把该线程对应的本地内存置为无效。再从主内存中读取共享变量。 锁获取和释放内存处理流程: 主要理解以下几句话: 1.线程A释放一个锁,实质上是线程A向接下来将要获取这个锁的某个线程发出了(线程A对共享变量所做修改的)消息。 2.线程B获取一个锁,实质上是线程B接收了之前某个线程发出的(在释放这个锁之前对共享变量所做修改的)消息。 3.线程A释放锁,随后线程B获取这个锁,这个过程实质上是线程A通过主内存向线程B发送消息。 参考博客:https://www.cnblogs.com/yuanfy008/p/9346925.html 来源: CSDN 作者: qq_43382364 链接: https://blog.csdn.net/qq_43382364/article/details/104558557

多线程进阶——JUC并发编程之CountDownLatch源码一探究竟

ぃ、小莉子 提交于 2020-02-28 11:17:32
1、学习切入点 JDK的并发包中提供了几个非常有用的并发工具类。 CountDownLatch 、 CyclicBarrier 和 Semaphore 工具类提供了一种并发流程控制的手段。本文将介绍CountDownLatch(闭锁)的实现原理。在了解闭锁之前需要先了解AQS,因为CountDownLatch的实现需要依赖于AQS共享锁的实现机制。 官方文档: https://docs.oracle.com/javase/8/docs/api/ 百度翻译如下: 一种同步辅助程序,允许一个或多个线程等待在其它线程中执行的一组操作完成。使用给定的计数初始化CountDownLatch。由于调用了countDown()方法,await方法阻塞直到当前计数为零,之后释放所有等待线程,并立即返回await的任何后续调用。这是一个一次性现象——计数不能重置。如果需要重置计数的版本,请考虑使用CyclicBarrier。倒计时锁存器是一种通用的同步工具,可用于多种目的。使用计数1初始化的倒计时锁存器用作简单的开/关锁存器或门:调用倒计时()的线程打开它之前,调用它的所有线程都在门处等待。初始化为N的倒计时锁存器可用于使一个线程等待N个线程完成某个操作或某个操作已完成N次。倒计时锁存器的一个有用特性是,它不要求调用倒计时的线程在继续之前等待计数达到零

Java虚拟机内存区域

馋奶兔 提交于 2020-02-28 10:20:34
Java虚拟机知识点总结(一) 文章目录 Java虚拟机知识点总结(一) 1、Java内存区域 1.1 Java内存区域 1.2 虚拟机对象 1、Java内存区域 1.1 Java内存区域 1、程序计数器 ​ 程序计数器是一块较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器。字节码解释器工作时通过改变这个计数器的值来选取下一条字节码指令,分支,循环,跳转,异常处理,线程恢复等功能都依赖这个计数器来完成。 为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各线程之间计数器互不影响,独立存储,我们称这类内存区域为“ 线程私有 ”的内存。 2、java虚拟机栈 与程序计数器一样,Java虚拟机栈也是 线程私有 的,它的生命周期和线程相同,描述的是Java方法执行的内存模型。 每个方法的执行都会创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息。 每个方法的调用到执行完成的过程,就是对应着一个栈在虚拟机栈中的入栈和出栈的过程 。 局部变量表 :存放编译期可知的各种基本数据类型,引用类型,局部变量表的大小在编译期便已经可以确定,在运行时期不会发生改变 。 栈的大小 :如果栈满了,StackOverFlowError,递归调用很常见。 如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError 异常。 3、本地方法栈

听说BAT这样的大公司,面试经常拿 ThreadLocal 考验求职者?(少侠留步)

这一生的挚爱 提交于 2020-02-28 07:19:56
今天,我们就来完完整整的学习下Threadlocal,争取以后再也不学了,因为看完今天这篇文章,你就对Threadlocal忘不了了! ThreadLocal 在线程中可以给我们提供一个线程内的本地局部变量,这样就可以减少在一个线程中因为多函数之间的操作导致共享变量传值的复杂性。 说白了,我们使用ThreadLocal可以做到在一个线程内随时随地的取用,而且与其他的线程互不干扰。 在一些特殊的情景中,应用ThreadLocal会带来极大的便利,不过很多人却搞不懂Threadlocal到底是个啥?在我们的面试中也经常会被问到Threadlocal,所以基于我们的实际应用以及应对面试,我们都有必要好好的学习下Threadlocal。 1、什么是Threadlocal? 我们既然要学习Threadlocal,那么我们先要知道它是个啥?我们从名字来看,Threadlocal意思就是线程本地的意思,官方是怎么定义它的,我们看看ThreadLocal的源码(基于jdk1.8)中对这个类的介绍: This class provides thread-local variables. These variables differ from* their normal counterparts in that each thread that accesses one (via its* {

python中的进程、线程(threading、multiprocessing、Queue、subprocess)

末鹿安然 提交于 2020-02-28 01:12:36
Python中的进程与线程 学习知识,我们不但要知其然,还是知其所以然。你做到了你就比别人NB。 我们先了解一下什么是进程和线程。 进程与线程的历史 我们都知道计算机是由硬件和软件组成的。硬件中的CPU是计算机的核心,它承担计算机的所有任务。 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源的管理和分配、任务的调度。 程序是运行在系统上的具有某种功能的软件,比如说浏览器,音乐播放器等。 每次执行程序的时候,都会完成一定的功能,比如说浏览器帮我们打开网页,为了保证其独立性,就需要一个专门的管理和控制执行程序的数据结构——进程控制块。 进程就是一个程序在一个数据集上的一次动态执行过程。 进程一般由程序、数据集、进程控制块三部分组成。我们编写的程序用来描述进程要完成哪些功能以及如何完成;数据集则是程序在执行过程中所需要使用的资源;进程控制块用来记录进程的外部特征,描述进程的执行变化过程,系统可以利用它来控制和管理进程,它是系统感知进程存在的唯一标志。 在早期的操作系统里,计算机只有一个核心,进程执行程序的最小单位,任务调度采用时间片轮转的抢占式方式进行进程调度。每个进程都有各自的一块独立的内存,保证进程彼此间的内存地址空间的隔离。 随着计算机技术的发展,进程出现了很多弊端,一是进程的创建、撤销和切换的开销比较大,二是由于对称多处理机(对称多处理机

Java并发高频面试题

雨燕双飞 提交于 2020-02-27 21:24:15
前面整理了Java基础、Mysql、Spring的高频面试题,今天为大家带来Java并发方面的高频面试题,因为并发知识不管在学习、面试还是工作过程中都非常非常重要,看完本文,相信绝对能助你一臂之力。 1、线程和进程有什么区别? 线程是进程的子集,一个进程可以有很多线程。每个进程都有自己的内存空间,可执行代码和唯一进程标识符(PID)。 每条线程并行执行不同的任务。不同的进程使用不同的内存空间(线程自己的堆栈),而所有的线程共享一片相同的内存空间(进程主内存)。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。 2、实现多线程的方式有哪些? 继承Thread类:Java单继承,不推荐; 实现Runnable接口:Thread类也是继承Runnable接口,推荐; 实现Callable接口:实现Callable接口,配合FutureTask使用,有返回值; 使用线程池:复用,节约资源; 更多方式可以参考我的文章使用Java Executor框架实现多线程 3、用Runnable还是Thread? 这个问题是上题的后续,大家都知道我们可以通过继承Thread类或者调用Runnable接口来实现线程,问题是,那个方法更好呢?什么情况下使用它?这个问题很容易回答,如果你知道Java不支持类的多重继承,但允许你调用多个接口。所以如果你要继承其他类

Java多线程与并发之ThreadLocal

戏子无情 提交于 2020-02-27 10:26:49
1. ThreadLocal是什么?使用场景 ThreadLocal简介 ThreadLocal是线程本地变量,可以为多线程的并发问题提供一种解决方式,当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 ThreadLocal使用场景 多个线程去获取一个共享变量时,要求获取的是这个变量的初始值的副本。每个线程存储这个变量的副本,对这个变量副本的改变不去影响变量本身。适用于多个线程依赖不同变量值完成操作的场景。比如: 多数据源的切换 spring声明式事务 2. ThreadLocal的使用案例 ThreadLocal类接口: void set(T value):设置当前线程的线程局部变量的值 T get():获取当前线程所对应的线程局部变量 void remove():删除当前线程局部变量的值,目的是为了减少内存的占用 T initialValue():该线程局部变量的初始值(默认值为null),该方法是一个protected的懒加载方法,线程第1次调用get()或set(T value)时才执行在,而且也是为了让子类覆盖而设计的。 public class ThreadLocalDemo { private static ThreadLocal

如何优雅的学习JVM,升华篇(三)

为君一笑 提交于 2020-02-26 15:51:16
此次内容和大家分享JVM中关于垃圾回收(Garbage Collect)的相关知识。 一、如何确定一个对象是垃圾? 要想进行垃圾回收,得先知道什么样的对象是垃圾。 1.1 引用计数法 对于某个对象而言,只要应用程序中持有该对象的引用,就说明该对象不是垃圾,如果一个对象没有任何指针对其引用,它就是垃圾。 注意: 如果A、B两个对象互相持有引用,会导致永远不能被回收。 1.2 可达性分析 通过GC Root的对象,可以开始向下寻找,看某个对象是否可达。 可以作为GC Root:类加载器、Thread、虚拟机栈的本地变量表、静态成员、常量引用、本地方法栈的变量等。 二、垃圾回收算法 2.1 标记-清除(Mark-Sweep) 标记(Mark) 找出内存中需要回收的对象,并把它们标记出来。此时堆中所有的对象都会被扫描一遍,从而才能确定需要回收的对象,比较耗时。 清除(Sweep) 清除掉被标记需要回收的对象,释放出对应的内存空间。 不足 1、标记和清除两个过程都比较耗时,效率不高 2、会产生大量的不连续的内存碎片,空间碎片太多可能会导致在以后程序运行的过程中需要分配较大的对象时,无法找到足够的连续内存而不得不提前触发一次垃圾回收动作。 2.2 复制(Copying) 将内存划分为两块相等的区域,每次只使用其中一块,如下图 当其中一块内存使用完了,就将还存活的对象复制到另一块上面