本地线程

Synchronized、Threadlocal、Volatile

孤人 提交于 2020-01-05 03:21:36
synchronized: synchronized叫做同步锁,操作起来方便,只需要在一个方法或把需要同步的代码块包装在它内部,那么这段代码就是同步的了,所有线程对这块区域的代码访问必须先持有锁才能进入,否则则拦截在外面等待正在持有锁的线程处理完毕再获取锁进入正因为它基于这种阻塞的策略,所以它的性能不太好,但是由于操作上的优势, 只需要简单的声明一下即可,而且被它声明的代码块也是具有操作的原子性。 threadlocal (本地单机) 用来提供线程内的局部变量,这样每个线程都自己管理自己的局部变量,别的线程操作的数据不会对我产生影响,互不影响 就是把变量分成很多个拷贝,每个线程拥有一个。这里没有所谓的最后的结果,每个线程单独操作自己的变量,和其他的变量没关系,互不干扰 ThreadLocalMap类的定义是在ThreadLocal类中,真正的引用却是在Thread类中。同时,ThreadLocalMap中用于存储数据的entry定义,它是一个Map,他的key是ThreadLocal实例对象。 1、JVM利用设置ThreadLocalMap的Key为弱引用,来避免内存泄露。 2、JVM利用调用remove、get、set方法的时候,回收弱引用 3、当ThreadLocal存储很多Key为null的Entry的时候,而不再去调用remove、get、set方法,那么将导致内存泄漏 4

java 虚拟机原理

青春壹個敷衍的年華 提交于 2020-01-04 17:59:12
什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,是一个虚构出来的计算机,它屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码,ByteCode), 就可以在多种平台上不加修改地运行。这背后其实就是JVM把字节码翻译成具体平台上的机器指令,从而实现“一次编写,到处运行(Write Once, Run Anywhere)”。 Java为什么能够跨平台? Java引入了字节码的概念,jvm 只能认识字节码,并将它们解释到系统的API调用。针对不同的系统有不同的jvm实现,有 Linux 版本的 jvm 实现,也有 Windows 版本的 jvm 实现,但是同一段代码在编译后的字节码是一样的。在不同的系统平台上运行是通过JAVA解释器将字节码解释为不同平台的机器码,在不同的 jvm 实现上会映射到不同系统的 API 调用,从而实现代码的不加修改即可跨平台运行。 JVM、JRE、JDK的关系 JRE(Java Runtime Environment,Java运行环境),面向Java程序的使用者,而不是开发者。JRE是运行Java程序所必须环境的集合,包含JVM标准实现及 Java核心类库。它包括Java虚拟机、Java平台核心类和支持文件 JDK(Java Development Kit

并发Bug之源有三,请睁大眼睛看清它们

会有一股神秘感。 提交于 2020-01-04 05:13:31
写在前面 生活中你一定听说过——能者多劳 作为 Java 程序员,你一定听过——这个功能请求慢,能加一层缓存或优化一下 SQL 吗? 看过中国古代神话故事的也一定听过——天上一天,地上一年 一切设计来源于生活,上一章 学并发编程,透彻理解这三个核心是关键 中有讲过,作为"资本家",你要尽可能的榨取 CPU,内存与 IO 的剩余价值,但三者完成任务的速度相差很大,CPU > 内存 > IO分,CPU 是天,那内存就是地,内存是天,那 IO 就是地,那怎样平衡三者,提升整体速度呢? CPU 增加缓存,还不止一层缓存,平衡内存的慢 CPU 能者多劳,通过分时复用,平衡 IO 的速度差异 优化编译指令 上面的方式貌似解决了木桶短板问题,但同时这种解决方案也伴随着产生新的 可见性,原子性,和有序性 的问题,且看 三大问题 可见性 一个线程对共享变量的修改,另外一个线程能够立刻看到,我们称为可见性 谈到可见性,要先引出 JMM (Java Memory Model) 概念, 即 Java 内存模型,Java 内存模型规定,将所有的变量都存放在 主内存 中,当线程使用变量时,会把主内存里面的变量 复制 到自己的工作空间或者叫作 私有内存 ,线程读写变量时操作的是自己工作内存中的变量。 用 Git 的工作流程理解上面的描述就很简单了, Git 远程仓库就是主内存,Git 本地仓库就是自己的工作内存

线程,进程,多进程,多线程。并发,并行的区别与关系

半世苍凉 提交于 2020-01-04 04:49:49
一:线程与进程 1.概念 线程:是程序执行流的最小单元,是系统独立调度和分配 CPU(独立运行)的基本单位。 进程:是资源分配的基本单位。一个进程包括多个线程。 进程 ≥ 线程 2.区别: 1.线程与资源分配无关,它属于某一个进程,并与进程内的其他线程一起共享进程的资源。 2.每个进程都有自己一套独立的资源(数据),供其内的所有线程共享。 3.不论是大小,开销线程要更“轻量级” 4.一个进程内的线程通信比进程之间的通信更快速,有效。(因为共享变量) 二 .多线程与多进程 多线程:同一时刻执行多个线程。用浏览器一边下载,一边听歌,一边看视频,一边看网页。。。 多进程:同时执行多个程序。如,同事运行 YY,QQ,以及各种浏览器。 三 .并发与并行 并发当有多个线程在操作时 ,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。.这种方式我们称之为并发(Concurrent)。 并行:当系统有一个以上 CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。 以下为详细的概念的讲解 并发: 并发,在 操作系统 中

C++并发编程 thread

空扰寡人 提交于 2020-01-04 04:47:33
std::thread   C++11在标准库中为多线程提供组件, 使用线程需要包含头文件 thread, 其命名空间为 std. 启动新线程 每个进程至少有一个线程: 执行main()函数的线程, 其余线程有其各自的入口函数(线程函数)。 当线程执行完线程函数后, 线程也会退出. 如果不传入线程函数(类似这种形式std::thread t;), 线程不会运行. 线程函数不能重载, 否则不能编译. 在为一个线程创建了一个 std::thread 对象后, 如果线程已启动(不传入线程序函数时, 线程不会启动), 必须要明确是加入(join)还是分离线程(detach). // 启动一个线程: void MyThread(const std::string& str) { PRINT_LINE_INFO(); std::cout << str << std::endl; } //std::thread t(MyThread, "Hello C..."); std::thread t([] { MyThread("Hello C..."); MyThread("Hello C2..."); }); // 对于类方法, 需要使用 std::bind. std::thread t(std::bind(&ThreadExample::MyThread, this, "msg"));

golang并发(1)介绍

做~自己de王妃 提交于 2020-01-04 04:46:52
概述 简而言之, 所谓并发编程是指在一台处理器上 “ 同时 ” 处理多个任务。 随着硬件的发展,并发程序变得越来越重要。 Web 服务器会一次处理成千上万的请求。平板电脑和手机 app 在渲染用户画面同时还会后台执行各种计算任务和网络请求。即使是传统的批处理问题 -- 读取数据,计算,写输出 -- 现在也会用并发来隐藏掉 I/O 的操作延迟以充分利用现代计算机设备的多个核心。计算机的性能每年都在以非线性的速度增长。 宏观的并发是 指在一段时间内 , 有多个程序在同时运行 。 并发在微观上,是指在同一时刻只能有一条指令执行,但多个程序指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个程序快速交替的执行。 并行和并发 并行 (parallel) : 指在同一时刻,有多条指令在 多个处理器 上同时执行。 并发 (concurrency) : 指在同一时刻只能有一条指令执行 , 但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段, 通过 cpu 时间片轮转 使多个进程快速交替的执行。 大师曾以咖啡机的例子来解释并行和并发的区别。 并行 是两个队列 同时 使用 两台 咖啡机 (真正的多任务) 并发 是两个队列 交替 使用 一台 咖啡机 ( 假 的多任务)

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

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

java java.util.concurrent.ThreadPoolExecutor 的翻译及解析

…衆ロ難τιáo~ 提交于 2020-01-04 01:10:02
基本描述 ExecutorService 是通过使用一种可能的线程池来执行每个被提交的任务, 一般配置使用 Executors 工厂方法. 线程池设法解决2个问题: 通常提供改良的性能当执行大量异步任务时, 由于减少了每个任务的调用支出以及提供一种约束和管理资源还有容纳当执行任务集合时消费他们的线程的手段. 每个 ThreadPoolExecutor 也维持一些基本的统计,像,已完成任务数量. 对于跨越大范围的上下文很有用,该类提供了很多可适应的参数和有扩展能力的钩子. 然而,程序员被怂恿使用更方便的 Executors 工厂方法 Executors#newCachedThreadPool (无限的线程池,并自动重用线程), Executors#newFixedThreadPool (固定线程大小), Executors#newSingleThreadExecutor (单后台线程), 它们为绝大部分场景预先设置好了. 另外,当手动配置和调制该类时按照下面的向导: 核心及最大线程池的规模(Core and maximum pool sizes) ThreadPoolExecutor 将自动调整线程池的规模(查看 getPoolSize 方法的解释),由核心线程池的规模(查看 getCorePoolSize 的解释),以及最大线程池的规模(查看 getMaximumPoolSize

JAVA运行时数据区

与世无争的帅哥 提交于 2020-01-03 23:04:22
引 JAVA虚拟机在执行JAVA程序的时候,会把它所管理的内存区域划分成若干个不同的数据区域。每个区域都有各自的功能,也有各自的创建和销毁时间,有的区域可能随着虚拟机的进程的启动而存在,有的区域可能根据用户线程的启动和结束来创建及销毁。 根据《Java虚拟机规范(JavaSE 7版)》的规定,Java虚拟机所管理的内存会被划分成以下几个运行时数据区域 下面将详细讲述各个数据区的作用 程序计数器(Program Counter Register): 程序计数器是一块比较小的内存区域,可以把它看成当前线程正在执行的字节码的行号指示器,虚拟机在解释字节码的时候,就是根据这个玩意来知道下一条需要执行的字节码在哪里(并非一定一行一行执行,如果遇到类似汇编中的jmp指令,可能会跳转到非下一行的指令),分支、跳转、循环、异常处理、线程恢复(比如被notify唤醒的线程)等基础功能都需要依赖于这个计数器。 Java虚拟机的多线程,它通过多个线程切换并分配CPU执行时间(CPU时间片)来实现多线程。也就是说,在一个瞬间(某一个确定的时刻),一个处理器(对于多核处理器来说,是指一个核心处理器)都只会执行一条线程中的指令。因此,在线程恢复后,为了能让该线程可以知道已经执行到哪一条指令,所以每一个线程都会有一个独立的程序计数器,独立工作,独立存储,互不影响,我们把这样每一个线程都会有的独立区域叫做

Java程序运行原理分析

梦想与她 提交于 2020-01-03 21:25:13
一、Java内存区域 线程隔离(独占)的数据区:虚拟机栈、本地方法栈、程序计数器 每个线程都会有它独立的空间,随线程的生命周而创建和销毁 所有线程共享的数据区:堆、方法区 所有线程都能访问这块内存数据,随虚拟机或GC而创建和销毁 1、程序计数器 程序计数器可以看作是当前线程所执行的字节码的行号指示器。字节码解释器就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。 由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。 如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值则为空(Undefined)。此内存区域是唯一一个在Java虚拟机规范中没有规定任何Out0fMemoryError情况的区域。 2、Java虚拟机栈 虚拟机栈是描述Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧,用于存储局部变量表,操作数栈,动态链接,方法出口等信息。每一个方法从调用直至执行完成的过程