本地线程

java内存模型

江枫思渺然 提交于 2020-01-30 04:32:40
关于内存模型网上资源简直不要太多,此文根据自己的理解总结了一下 博客小白,文章为原创,里面一些个人的观点可能不太准确或严谨,若有问题欢迎各路大神批评指正 首先是上图: java的内存可大范围分为两类: 一、线程隔离(线程私有): 所谓线程隔离也就是说这个区域的内存各个线程间相互独立,互不影响 1. 程序计数器(program counter register): 是一块比较小的内存空间,作用可以看做是当前线程执行字节码的行号指示器 在虚拟机的概念模型里,字节码解释器就是通过改变计数器的值来选取下一条要执行的字节码 比如分支,循环,跳转,异常处理等 说的简单些就是用来控制程序的走向; 一个处理器在一个时间只会处理一条线程中的指令,因此每条线程都会有一个单独的程序计数器,各个线程间互不影响 如果线程正在执行一段java方法,那么计数器记录的就是虚拟机指令的的地址; 如果执行的是native方法,计数器的值为空(Undefined) 程序计数器是java内存模型中唯一不会出现outOfMemory的地方 2. 虚拟机栈(java virtual machine stacks) 虚拟机栈也就是我们一般常说的栈 每个方法被执行的时候都会同时创建一个栈帧,用于存储局部变量表,操作栈,动态链接,方法出口等 每一个方法被执行到结束的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程

【Java并发编程】之五:volatile变量修饰符—意料之外的问题

耗尽温柔 提交于 2020-01-29 15:49:31
volatile用处说明 ​ 在JDK1.2之前,Java的内存模型实现总是从主存(即共享内存)读取变量,是不需要进行特别的注意的。而随着JVM的成熟和优化,现在在多线程环境下volatile 关键字 的使用变得非常重要。 在当前的Java内存模型下, 线程 可以把 变量 保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个 变量 的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。 要解决这个问题,就需要把 变量 声明为volatile(也可以使用同步,参见 http://blog.csdn.net/ns_code/article/details/17288243 ),这就指示JVM,这个变量是不稳定的,每次使用它都到主存中进行读取。一般说来,多任务环境下,各任务间共享的变量都应该加volatile修饰符。 Volatile修饰的 成员变量 在每次被 线程 访问时,都强迫从 共享内存 中重读该成员变量的值。而且,当 成员变量 发生变化时,强迫线程将变化值回写到 共享内存 。这样在任何时刻,两个不同的线程总是看到某个 成员变量 的同一个值。 Java语言 规范中指出:为了获得最佳速度,允许线程保存共享 成员变量 的私有拷贝,而且只当线程进入或者离开 同步代码块 时才将私有拷贝与共享内存中的原始值进行比较。

Java内存模型与线程

假如想象 提交于 2020-01-29 07:32:02
Java内存模型与线程 每秒事务处理数(Transactions Per Second,TPS)、 Java语言和虚拟机提供了许多工具,把并发编程的门槛降低了不少。另外,各种中间件服务器、各类框架 12.2 硬件的效率与一致性 现代计算机系统都不得不加入一层读写速度尽可能接近处理器运算速度的高速缓存(Cache)来作为内存与处理器之间的缓冲: 为了解决一致性的问题,需要各个处理器访问缓存时都遵循一些协议,在读写时要根据协议来进行操作,这类协议有MSI、MESI(IllinoisProtocol)、MOSI、Synapse、Firefly及Dragon Protocol,等等 为了使得处理器内部的运算单元能尽量被充分利用,处理器可能会对输入代码进行乱序执行(Out-Of-Order Execution)优化,处理器会在计算之后将乱序执行的结果重组,保证该结果与顺序执行的结果是一致的,类似,Java虚拟机的即时编译器中也有类似的指令重排序(Instruction Reorder)优化。 12.3 Java内存模型 用来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果。 12.3.1 主内存与工作内存 此处的变量包括了实例字段、静态字段和构成数组对象的元素,但是不包括局部变量与方法参数,因为后者是线程私有的[插图],不会被共享

java并发基础知识

跟風遠走 提交于 2020-01-28 20:44:52
  这几天全国都是关键时候,放假了,还是要学习啊!很久没有写博客了,最近看了一本书,有关于java并发编程的,书名叫做“java并发编程之美”,讲的很有意思,这里就做一个笔记吧!     有需要openjdk8源码的,可以直接下载 链接:https://pan.baidu.com/s/1_uT99PLxH-STcs0zl0Mhuw 提取码:ov5b 一.了解并发和并行   并发:指的是 同一时间段内 多个任务在执行,并且没有执行结束;就好像你用一个手机看视频,你一下子想看熊出没,一下子又想看喜羊羊,那么你会怎么办?可以这个视频看几秒钟,然后那个视频看几秒钟,最关键的是当你从熊出没->喜羊羊,然后再跳到熊出没的时候,可以直接跳到上次看的记录的位置,这个才是并发最重要的地方;   在这里,你的眼睛就相当于一个cpu,在来回的切换视频,每个视频就是一个线程,然后可以跳转回上次的最后观看的位置,这功能就是类似PC计数器的作用,可以保存每个线程切换时候的上下文;   并行:理解了上面的并发,那么并行就很好理解!记得看过火影没有,可以知道鸣人用影分身修炼的情节,这个就是并行!如果你会影分身,那么你和你的分身分别用一个手机去看熊出没和喜羊羊,然后解除影分身,那么你就一下子同时看完两集了!哈哈哈,这个比喻还行吧!其实就是有两个CPU分别去执行一个线程,再把运行后的结果汇总   在多线程编程实践中

volatile关键字

吃可爱长大的小学妹 提交于 2020-01-28 20:42:38
一、简介 volatile是Java提供的一种轻量级的同步机制。Java 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量,相比于synchronized(synchronized通常称为重量级锁),volatile更轻量级,因为它不会引起线程上下文的切换和调度。但是volatile 变量的同步性较差(有时它更简单并且开销更低),而且其使用也更容易出错。 二、并发编程的3个基本概念 (1)原子性 ​ 定义: 即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。 ​ 原子性是拒绝多线程操作的,不论是多核还是单核,具有原子性的量,同一时刻只能有一个线程来对它进行操作。简而言之,在整个操作过程中不会被线程调度器中断的操作,都可认为是原子性。例如 a=1是原子性操作,但是a++和a +=1就不是原子性操作。Java中的原子性操作包括: ​ a. 基本类型的读取和赋值操作,且赋值必须是数字赋值给变量,变量之间的相互赋值不是原子性操作。 ​ b.所有引用reference的赋值操作 ​ c.java.concurrent.Atomic.* 包中所有类的一切操作 (2)可见性 ​ 定义: 指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。 ​ 在多线程环境下

Python进程、线程、协程之间的关系

喜你入骨 提交于 2020-01-28 15:22:27
一、从操作系统角度 操作系统处理任务, 调度单位是 进程 和 线程 。 1.进程: 表示一个程序的执行活动 (打开程序、读写程序数据、关闭程序) 2.线程: 执行某个程序时, 该进程调度的最小执行单位 (执行功能1,执行功能2) 一个程序至少有一个进程 一个进程至少有一个线程 1.并行: 需要处理的任务数 == CPU核心数量 两个任务 两个核心 任务1:------------- 任务2:------------- 2.并发: 需要处理的任务数 > CPU核心数量 三个任务 一个核心 任务1: ----- ------ 任务2: ------ 任务3: ------ 二、从程序角度 多进程和多线程 表示:当前程序可以同时执行多个任务 进程和线程都是由 操作系统调度完成 1.进程:    每个进程都是有自己独立的内存空间,不同进程之间的内存空间是不能共享。 不同进程之间的通信是由操作系统来完成的。 不同进程之间的通信效率低切换开销也大。 2.线程:   一个进程下可以有多个线程,同一个进程内的线程可以共享内存空间. 不同线程之间的通信 有进程 管理。 不同线程之间的通信效率高,切换开销小。 3.互斥锁:   共享意味着多个线程的竞争 会导致不安全问题。 为了保护内存空间的数据不被多个线程同时读写, 导致数据隐患, 于是诞生了" 互斥锁 "。 "互斥锁":

进程、线程、以及它们之间的区别与联系

我的未来我决定 提交于 2020-01-28 15:06:08
一、进程简介 1.1 进程概念的引入 计算机中,CPU是最宝贵的资源,为了提高CPU的利用率,引入了多道程序设计的概念。当内存中多个程序存在时,如果不对人们熟悉的“程序”的概念加以扩充,就无法刻画多个程序共同运行时系统呈现出的特征。 多道程序设计:是指允许多个作业(程序)同时进入计算机系统的内存并启动交替计算的方法。 也就是说,内存中多个相互独立的程序均处于开始和结束之间。 从宏观上看是并行的,多道程序都处于运行过程中,但尚未运行结束; 从微观角度上看是串行的,各道程序轮流的占用CPU交替的执行。 引入多道程序设计技术可以提高CPU的利用率,充分发挥计算机硬部件的并行性。 多道程序系统中,程序具有:并行、制约以及动态的特征。程序概念难以便是和反映系统中的情况,所以引入了进程这一概念。 1.2 程序是什么 说起进程,就不得不说下程序。先看定义:程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个 静态 的概念。系统实际上是出于不断变化的状态中,程序不能反映这种动态性。 而进程则是在处理机上的一次执行过程,它是一个 动态 的概念。这个不难理解,其实进程是包含程序的,进程的执行离不开程序,进程中的文本区域就是代码区,也就是程序。 1.3 进程是什么 1.3.1 进程的概念 进程的定义: 进程是据有独立功能的程序在某个数据集合上的一次运行活动

课程总结

对着背影说爱祢 提交于 2020-01-28 04:12:33
课程总结 大二第一个学期已经结束了,在此对本学期进行一个总结,本学期从对Java一无所知到表面理解,其中也是花了不少时间的,但也仅仅是表面上的了解,去年的c语言到今年的java这更加是我们对学习的一个丰富化,对知识的了解更多了,在以后的学习日子里,我会更加的对知识基础进行巩固。 一、Java基础程序设计 1、Java的数据类型可分为基本数据类型和引用数据类型两种。 2、布尔类型的变量,只有ture和false两个值。 3、数据类型的转换可分为“自动类型转换”与“强制类型转换”两种。 4、算术运算符的成员有加法运算符、减法运算符、乘法运算符、除法运算符、余数运算符。 5、if语句可依据判断的结果来决定程序的流程。 6、自增与自减运算符有着相当大的便利性,善用他们可提高程序的简洁程度。 8、括号是用来处理表达式的优先级的,也是Java的运算符。 9、占用较少字节的数据类型会转换成占用较多字节的数据类型;有short和int类型,则用int类型;字符类型会转换成short类型;int类型转换成float类型;布尔类型不能转换成其他的类型。 二、面向对象编程 1、构造方法可以为类中的属性初始化,构造方法与类名称相同,无法返回值声明,如果在类中没有明确的定义出构造方法,则会自动生成一个无参的声明都不做的构造方法,在一个类中的构造方法可以重载,但是每个类都至少有一个构造方法。 2

ThreadLocal如何解决内存泄漏

老子叫甜甜 提交于 2020-01-28 03:08:12
ThreadLocal我主要从以下接个方面说明: 基础 理解 接口方法 源码分析 ThreadLocal如何解决内存泄漏 1、基础 ThreadLocal从字面意思为:线程本地。它是一个关于创建线程局部变量的类。 通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。而使用ThreadLocal创建的变量只能被当前线程访问,其他线程则无法访问和修改。 有一个误区是ThreadLocal的目的是为了解决多线程访问资源时的共享问题 但ThreadLocal 并不解决多线程 共享 变量的问题。既然变量不共享,那就更谈不上同步的问题。 2、理解 ThreadLoal 变量,它的基本原理是,同一个 ThreadLocal 所包含的对象(对ThreadLocal< String >而言即为 String 类型变量),在不同的 Thread 中有不同的副本(实际是不同的实例)。这里有几点需要注意: 因为每个 Thread 内有自己的实例副本,且该副本只能由当前 Thread 使用。这是也是 ThreadLocal 命名的由来 既然每个 Thread 有自己的实例副本,且其它 Thread 不可访问,那就不存在多线程间共享的问题 既无共享,何来同步问题,又何来解决同步问题一说? 那 ThreadLocal 到底解决了什么问题,又适用于什么样的场景? ThreadLocal

线程安全与锁优化

你说的曾经没有我的故事 提交于 2020-01-27 16:42:25
1.线程安全: 当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方法进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那这个对象就是线程安全的。 2.Java语言中的线程安全  根据线程安全的安全程度由强到弱来排序,我们可以把Java语言中各种操作共享的数据分为以下5类:不可变、绝对线程安全、相对线程安全、线程兼容和线程对立。    1)不可变: 不可变的对象一定是线程安全的;Java语言中,如果共享数据是一个基本数据类型,那么只要在定义时使用final关键字修饰它就可以保证它是不可变的。如果共享数据是一个对象,那就需要保证对象的行为不会对其状态产生任何影响,即把对象中带有状态的变量都声明为final,这样在构造函数结束之后,它就是不可变的。    2)绝对线程安全: 就是一个类在任何运行时环境下,调用者都不需要任何额外的同步措施。在Java API中标注自己是线程安全的类,大多数都不是绝对线程安全的。    3)相对线程安全: 就是我们通常所讲的线程安全,它需要保证对这个对象单独的操作是线程安全的,我们在调用时不需要做额外的保障措施。但对于一些特定顺序的连续调用,就可能需要在调用端使用额外的同步手段来保证调用的正确性。    4)线程兼容: 指对象本身并不是线程安全的