本地线程

JVM 的内存模型

折月煮酒 提交于 2020-01-26 18:56:17
为什么要了解? 很多做Android开发的同学会问,我们为什么要了解这个呢?首先移动端资源有限,我们了解jvm的内存模型,便于我们更好的管理客户端的内存。 什么是JVM? java代码的执行过程如下图: 运行时数据区可分为:方法区、堆、虚拟机栈、本地方法栈、程序计数器五个部分。 概述 方法区:线程共享数据,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 堆:线程共享数据,主要是存放对象实例和数组。内部会划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer, TLAB)。可以位于物理上不连续的空间,但是逻辑上要连续。 虚拟机栈:线程隔离数据,每个方法在执行时都会床创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行结束,就对应着一个栈帧从虚拟机栈中入栈到出栈的过程。 本地方法栈:线程隔离数据,区别于 Java 虚拟机栈的是,Java 虚拟机栈为虚拟机执行 Java 方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。 程序计数器:线程隔离数据,字节码解释器工作是就是通过改变这个计数器的值来选取下一条需要执行指令的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖计数器完成。 1.方法区  

Spark学习之路 (十三)SparkCore的调优之资源调优JVM的基本架构[转]

筅森魡賤 提交于 2020-01-26 18:14:10
JVM的结构图 Java内存结构 JVM内存结构主要有三大块:堆内存、方法区和栈。 堆内存是JVM中最大的一块由年轻代和老年代组成,而年轻代内存又被分成三部分,Eden空间、From Survivor空间、To Survivor空间,默认情况下年轻代按照8:1:1的比例来分配; 方法区存储类信息、常量、静态变量等数据,是线程共享的区域,为与Java堆区分,方法区还有一个别名Non-Heap(非堆); 栈又分为java虚拟机栈和本地方法栈主要用于方法的执行。 如何通过参数来控制各区域的内存大小 控制参数 -Xms设置堆的最小空间大小。 -Xmx设置堆的最大空间大小。 -XX:NewSize设置新生代最小空间大小。 -XX:MaxNewSize设置新生代最大空间大小。 -XX:PermSize设置永久代最小空间大小。 -XX:MaxPermSize设置永久代最大空间大小。 -Xss设置每个线程的堆栈大小。 没有直接设置老年代的参数,但是可以设置堆空间大小和新生代空间大小两个参数来间接控制。 老年代空间大小=堆空间大小-年轻代大空间大小 JVM和系统调用之间的关系 方法区和堆是所有线程共享的内存区域;而java栈、本地方法栈和程序员计数器是运行是线程私有的内存区域。 JVM各区域的作用 Java堆(Heap) 对于大多数应用来说,Java堆(Java Heap

如何实现线程安全?

谁说我不能喝 提交于 2020-01-26 15:08:00
文章目录 避免共享 不可变 可重入代码 线程封闭 必须共享 互斥同步 非阻塞同步 什么是线程安全?下面是我摘自java并发编程书里给的解释: 当多个线程访问某个类时,这个类始终都能表现出正确的行为,那么就称这个类是线程安全的。 这个解释听的是不是云里雾里?我们说的通俗一点: 线程安全就是多线程并发访问的时候,线程之间所共享的资源不会被污染或被破坏。 我们知道线程共享的内存区域主要就是java堆,而java堆主要存的就是对象和数组,所有的全局变量都存储在堆中。也就是说我们想保证线程安全,就需要保证全局变量和堆内的对象不会受其他线程影响。 由此,我们可以从数据共享和不共享两个方面来讨论实现线程安全的方式。 避免共享 通过避免共享,让所有资源都编程线程私有,达到线程安全。主要实现方法有三种: 不可变 可重入代码 线程封闭 不可变 使用final类型 通过使用final类型修饰,发布不可变对象。 String属于不可变对象,可直接使用。 使用volatile类型 通过使用Volatile类型修饰,发布不可变对象。 volatile类型修饰的变量只适用于读多写少的情况,只能确保其可见性。如果要保证线程安全,则需要保证只有单个线程去修改。 可重入代码 若一个程序或子程序可以安全的被并行执行,则称其为可重入(reentrant),即允许多个进程同时访问。 可重入代码

Spring框架学习笔记-ThreadLocal基础知识

守給你的承諾、 提交于 2020-01-26 07:33:25
在前面我们已经说过,Spring通过各种模板降低了开发者使用各种数据持久化技术的难度。这些模板类都是线程安全的,也就是说,多个DAO可以复用同一个模板实例而不会发生冲突。 我们使用模板类访问底层数据,根据持久化技术的不同,模板类需要绑定数据连接或会话的资源。但这些资源本身是非线性安全的,也就是说它们不能在同一时刻被多个线程共享,虽然模板类通过资源池获取数据连接或对话,但资源池本身解决的是数据连接或对话的缓存问题,并非数据连接或对话的线程安全问题。 按照传统经验,如果某个对象是非线程安全的,在多线程环境下,对对象的访问必须采用线程同步。但模板类并未采用线程同步机制,因为线程同步会降低并发性,影响系统性能。 那么模板类是靠的什么,可以在无需线程同步的情况下就化解了线程安全的难题呢?答案就是ThreadLocal! ThreadLocal在Spring里发挥着重要的作用,在管理request作用域的Bean、事务管理以及任务调度、AOP等模块都出现了它们的身影,起着举足轻重的作用。要想了解Spring事务管理的底层技术,ThreadLocal是必须攻克的山头堡垒。 1.ThreadLocal是什么 ThreadLocal是服务于Thread的一种 本地私有数据机制 ,threadlocalvariable(线程局部变量), 即为每一个使用该变量的线程都提供一个变量值的副本

分布式锁,进程锁,线程锁到底是什么

故事扮演 提交于 2020-01-26 02:49:29
在分布式集群系统的开发中,线程锁往往并不能支持全部场景的使用,必须引入新的技术方案分布式锁。   线程锁:大家都不陌生,主要用来给方法、代码块加锁。当某个方法或者代码块使用锁时,那么在同一时刻至多仅有有一个线程在执行该段代码。当有多个线程访问同一对象的加锁方法/代码块时,同一时间只有一个线程在执行,其余线程必须要等待当前线程执行完之后才能执行该代码段。但是,其余线程是可以访问该对象中的非加锁代码块的。   进程锁:也是为了控制同一操作系统中多个进程访问一个共享资源,只是因为程序的独立性,各个进程是无法控制其他进程对资源的访问的,但是可以使用本地系统的信号量控制(操作系统基本知识)。   分布式锁:当多个进程不在同一个系统之中时,使用分布式锁控制多个进程对资源的访问。 分布式锁到底是什么,怎么实现?   intsmaze说简单点,实现分布式锁必须要依靠第三方存储介质来存储锁的元数据等信息。比如分布式集群要操作某一行数据时,这个数据的流水号是唯一的,那么我们就把这个流水号作为一把锁的id,当某进程要操作该数据时,先去第三方存储介质中看该锁id是否存在,如果不存在,则将该锁id写入,然后执对该数据的操作;当其他进程要访问这个数据时,会先到第三方存储介质中查看有没有这个数据的锁id,有的话就认为这行数据目前已经有其他进程在使用了,就会不断地轮询第三方存储介质看其他进程是否释放掉该锁

Volatile作用

大兔子大兔子 提交于 2020-01-25 21:38:06
volatile的用处: 在JDK1.2之前,Java内存模型总是从主存(共享内存)中读取变量值,是不需要进行特别注意的。 在当前Java内存模型下,线程可以把变量保存在本地内存,如寄存器中,而不是直接在主存中进行读写。这就造成了一个线程在主存中修改了一个变量的值,而另一个线程还在使用它在寄存器中的变量值的拷贝,造成了了数据不一致。 为了解决这个问题,我们就需要把该变量声明为volatile,这就指示JVM,这个变量是不稳定的,每次使用他都要去主存中读取,而不是本地内存,一般说来,多任务环境下,各任务间共享的变量,都应该使用volatile进行修饰。 volatile修饰的变量,在被每次线程访问时,都强迫从共享内存中重读该变量的值。而且当该变量变化时,都强迫线程将变化的值写到共享内存中,这样在任何时刻,两个不同的线程总是看到该变量的同一个值。 Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才将私有拷贝与共享内存中的原始值进行比较。 这样当多个线程同时与某个对象交互时,就必须注意到要让线程及时的得到共享成员变量的变化。而volatile关键字就是提示JVM:对于这个成员变量,不能保存它的私有拷贝,而应直接与共享成员变量交互。 volatile是一种稍弱的同步机制,在访问volatile变量时不会执行加锁操作

Java之ThreadLocal原理分析

独自空忆成欢 提交于 2020-01-25 16:58:24
简介 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。从线程的角度看,目标变量就象是线程的本地变量,这也是类名中“Local”所要表达的意思。所以,在Java中编写线程局部变量的代码相对来说要笨拙一些,因此造成线程局部变量没有在Java开发者中得到很好的普及。引自@ 枫之逆 人们常说,锁是一种以时间换空间的机制,而ThreadLocal正好是以空间换时间的。 和锁的比较 为什么要先强调这一点,因为从简介上看,容易使人们联想到ThreadLocal似乎是一种解决Java多线程环境中线程同步与线程安全方法,其实不然,这里要设计到两个概念:线程安全,线程同步,事实上,ThreadLocal只解决线程安全的问题,并不能解决线程同步的问题,这也造成在刚学习的时候,我总是在苦想,ThreadLocal既然为每个线程拷贝一份变量,那怎么再进行同步呢?查了很多资料后才想明白,ThreadLocal并不是用来解决线程同步的,所以它与锁可以说是没有什么关系的,彼此各有所长,不能代替

python中多线程与多进程的区别和联系

纵然是瞬间 提交于 2020-01-25 15:56:41
python多线程实现 python多线程和多进程的区别 python多线程爬虫 python多线程坑 python多线程可以在windows下实现吗 python多线程并发 python多线程变量共享 python多线程是并发还是并行 python多线程实例 python多线程condition Python中多进程与多线程的区别有:线程需要在进程中执行,一个进程可包含多个线程;进程可共享同个地址空间而进程共享物理地址,线程创建简单,进程需要对父进程克隆等等 今天将要分享的是Python中多进程与多线程的相关知识及区别,接下来将在文章中具体介绍,具有一定的参考价值,希望对大家有所帮助 更多的详细内容学习点我 【推荐课程: Python教程 】 线程的概念: 线程是操作系统中进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程可以有多个线程,每条线程可以同时执行不同的任务。一个线程可以看作一个cpu执行时所需要的一串指令 多线程 在Python的标准库中提供了两个模块:_thread和threading,_thread是低级模块不支持守护线程,当主线程退出时,所有子线程都会被强行退出。而threading是高级模块,用于对_thread进行了封装支持守护线程

Java并发--线程间协作的两种方式:wait、notify、notifyAll和Condition

半世苍凉 提交于 2020-01-25 06:42:00
  在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作。比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界资源(即队列)的占用权。因为生产者如果不释放对临界资源的占用权,那么消费者就无法消费队列中的商品,就不会让队列有空间,那么生产者就会一直无限等待下去。因此,一般情况下,当队列满时,会让生产者交出对临界资源的占用权,并进入挂起状态。然后等待消费者消费了商品,然后消费者通知生产者队列有空间了。同样地,当队列空时,消费者也必须等待,等待生产者通知它队列中有商品了。这种互相通信的过程就是线程间的协作。   今天我们就来探讨一下Java中线程协作的最常见的两种方式:利用Object.wait()、Object.notify()和使用Condition   以下是本文目录大纲:    一.wait()、notify()和notifyAll()   二.Condition    三.生产者-消费者模型的实现   转载原文链接:http://www.cnblogs.com/dolphin0520/p/3920385.html 一.wait()、notify()和notifyAll()   wait()、notify()和notifyAll()是 Object类中的方法: /** * Wakes

android JVM运行机制

我的未来我决定 提交于 2020-01-25 03:53:41
1 JVM启动流程 2 JVM基本结构 2.1 PC寄存器 每个线程拥有一个PC寄存器 在线程创建时创建 指向下一条指令的地址 执行本地方法时,PC的值为undefined 2.2 方法区 保存装载的类信息: 类型的常量池 字段、方法信息 方法字节码 通常和永久区(Perm)关联在一起 注意: JDK6时,String等常量信息至于方法 JDK7时,已经移动到了堆 2.2 Java堆 和程序开发密切相关 应用系统对象都保存在Java堆中 所有线程共享Java堆 对分代GC来说,堆也是分代的 GC的主要工作区间 2.3 Java栈 线程私有 栈由一系列帧组成(因此Java栈也叫Java帧栈) 帧保存一个方法的局部变量、操作数帧、常量池指针 每一次方法调用创建一个帧,并压栈 局部变量表 包括参数和局部变量 public class StackDemo { public static int runStatic ( int i, long l, float f, Object o, byte b ) { return 0 ; } public int runInstance ( char c, short s, boolean b ) { return 0 ; } } 操作数栈 Java没有寄存器,所有参数传递使用操作数栈 public static int add ( int a