线程

记录一下jvm的相关知识点

有些话、适合烂在心里 提交于 2020-03-11 13:22:06
java 运行时数据区域: 程序计数器 => (每个线程都包含一个程序计数器)用来记录字节码执行的行号,字节码指令的循环,跳转,异常处理,线程恢复等需要依靠计数器。 Java虚拟机栈 => 主要用来描述Java方法执行的内存模型,(每个线程都包含一个虚拟机栈)主要用来处理方法的调用,虚拟机栈中的存储单元是栈帧,方法在执行的同时都会在虚拟机栈中创建一个栈帧,栈帧包含操作数栈,局部变量表,动态链接和方法出口等,每个方法从调用到执行完毕都对应着一个栈帧在虚拟机栈中的入栈和出栈的过程。局部变量表的存储单位为slot(4个字节),因此double 和long类型需要占用2个slot的存储空间。 栈的深度有一定限制,当深度操作最大的调用栈大小会出现StackOverflowError异常。 本地方法栈 => 为虚拟机执行java方法的服务(native方法),类似虚拟机栈 java堆 => 对象和数组存储的场所,也是gc收集器的主要管理区域,现在收集器基本采用分代收集算法,可通过-Xmx -Xms来分配堆内存大小,当堆内存无法分配内存时,会出现OutOfMemoryError异常。 方法区 => 用于存储已被虚拟机加载的类信息,静态变量,常量以及即时编译器编译后的代码等,方法区无法分配内存是会出现OutOfMemoryError异常。 运行时常量池 =>方法区的一部分

Android 性能优化工具之 TraceView

橙三吉。 提交于 2020-03-11 13:11:12
简介 TraceView 是 Android SDK 中内置的一个工具,它可以加载 trace 文件,用图形的形式展示代码的执行时间、次数及调用栈,主要便于我们分析及优化方法的执行。 官方文档 参考: TraceView 使用文档 使用 1. 获取 .trace 报表 第一步:点击Android Studio中的Tools/Android/Android Device Monitor,打开调试界面。 第二步:如下面截图所示,选中要分析的应用包名,点击 Start Method Profiling 按钮,之后就会开始跟踪: 第三步:进入应用内进行操作,操作完毕后,再次点击上面的按钮Stop Method Profiling,等待一会,就会在右边的窗口生成分析的报表,将鼠标上移到红框的文件名处,可以看到保存的位置,我们可以把它保存起来以便之后分析跟踪问题: 2. 分析 .trace 报表 获取完报表之后,我们就可以通过它来分析,这个区域分为三个部分: 红色区域:列出了运行的各个线程。 蓝色区域:线程在一段时间内的运行情况,我们点击有颜色的地方,就可以定位到具体做了哪些操作。 紫色区域:方法调用的具体情况。 前面两个区域都比较好理解,我们主要看一下紫色区域的每一列具体的含义: 上面的表格中,一部分单位是百分比,另一部分是ms,要注意区别,除此之外,有两点需要解释一下:

多线程并发问题

核能气质少年 提交于 2020-03-11 13:05:43
多线程: --并发问题 线程对于内存数据的访问会提供一个内存副本供其使用,在线程使用结束时,将副本内容merge到内存中。以下的图就是线程并发的问题。 数据1被线程1和线程2都拿走各拿的都是一个拷贝的副本,这个时候都对数据+1,在结束时副本数据都为2,本来应为3,merge后数据也为2。 voliate 修饰词: 强制从内存中获取,如果有变更则直接更新内存,可以大范围的解决并发冲突,但是不能完全消除掉。 synchronized: 表示将内存给锁住,一次只能有一个线程去取,取完了再下一个,这样保证安全,但是会造成堵塞。 目前java7,8用的较新的有: 1. AtomicInteger 做计数用,内部使用voliate和Unsafe类。 对于UnSafe类,内部修饰符都是native即会调用系统语言操作内存,有指针的引入。其中pack()和unpack()控制线程的挂起还是继续。 CAS ---比较并交换(compare and swap)是一条CPU并发 CAS方法控制对CPU原子指令操作,保证顺序执行并不会被打断实现免疫死锁。 但ABA问题就需要使用AtomicStampedReference类加入时间戳来判断是否内存的数据有没有过改动。 Lock和unLock也就是通过 调用CAS将要锁的对象预期值设为null,使得无法进入cpu处理,然后会在门外排队等候,等到自己又被排除掉

java子线程中获取父线程的threadLocal中的值

妖精的绣舞 提交于 2020-03-11 12:48:24
我们都知道线程本地变量表也就是ThreadLocal在我们做线程级的数据隔离时非常好用,但是有时候我们会想如何让子线程获取到父线程的ThreadLocal,其实在线程中除了ThreadLocal外还有InheritableThreadLocal,顾名思义,可继承的线程变量表,可以让子线程获取到父线程中ThreadLocal的值。 public class BaseTest { public static final InheritableThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>(); public static final ThreadLocal<String> threadLocal = new ThreadLocal<>(); public static void main(String[] args) { inheritableThreadLocal.set("Inheritable hello"); threadLocal.set("hello"); new Thread(()->{ System.out.println(String.format("子线程可继承值:%s",inheritableThreadLocal.get())); System.out

Java多线程系列--利用自旋原理来无锁实现“只创建一次”的场景

自古美人都是妖i 提交于 2020-03-11 10:09:21
相信看过之前几篇自旋锁实现的同学对设计一个自旋锁会有一定的感觉,有几个实现的要点很实用: 1. 使用AtomicBoolean原子变量的getAndSet(true)方法来实现并发情况下,找到第一个成功执行方法的线程。这个技巧经常使用,在并发编程中经常会遇到这种需求 2.经常会使用volatile boolean类型的变量在多个线程之间同步状态,需要注意的是,对volatile变量的修改只具有可见性,不具有原子性(比如++操作)。 3. 使用一个AtomicReference原子变量的getAndSet方法来创建一个虚拟的链表结构,原理也是CAS操作,在队列锁中经常使用 这篇结合一个实例来说说如何灵活地利用这些技巧实现无锁的能力。 在实际开发中会经常遇到“只创建一次”的场景,这里说的“只创建一次”不是说单实例模式。单实例模式也是解决只创建一次的问题,关于单实例模式有很多技巧来实现高并发情况下只创建一个对象的问题,这里不讨论。 单实例模式解决的问题是所有线程都公用一个静态的引用,可以用volatile变量来标示这个静态引用,从而在所有线程之间共享这个静态引用的状态是否已经改变。 这里说的“只创建一次”的场景是这个需要创建一次的对象不是直接被全局的引用所引用,而是间接地被引用。经常有这种情况,全局维护一个并发的ConcurrentMap, Map的每个Key对应一个对象

C++11 原生标准多线程

空扰寡人 提交于 2020-03-11 10:06:20
之所以称之为C++11原生标准多线程,因为在C++中C++11版本才加入的多线程。所谓原生也就是C++语言自带的,区别于其他库实现,比如POSIX,Boost,winAPI,QT【藐视很少有人提到QT的多线程,不过我就是因为要使用QT的多线程库,才认真学习C++11原生标准多线程的。】等的多线程实现。关于系统学习C++原生多线程编程的书,我推荐由Anthony Williams所著的《Cpp Concurrency In Action》,中文版由陈晓伟所译。Anthony Williams是C++11多线程标准起草着之一。 《C++ Concurrency in Action》中文版 在线阅读可以访问陈晓伟的gitbook,他是免费开源的。 关于并发 《C++ Concurrency in Action》一书中对并发通俗的解释: 最简单和最基本的并发,是指两个或更多独立的活动同时发生。 并发在生活中随处可见,我们可以一边走路一边说话,也可以两只手同时作不同的动作,还有我们每个人都过着相互独立的生活——当我在游泳的时候,你可以看球赛,等等。 为什么使用并发 : 《C++ Concurrency in Action》中介绍的有点抽象,有点深奥。通俗的讲,就是 我们希望在相同的时间内做更多的事情: 把关注点(SOS)【我们要做的事情、任务】分离。还有就是 我们希望通过并发提高一下性能

java线程并发工具类

半世苍凉 提交于 2020-03-11 09:16:38
  本次内容主要讲 Fork-Join、 CountDownLatch、CyclicBarrier以及Callable、Future和FutureTask,最后再手写一个自己的FutureTask,绝对干货满满! 1、 Fork-Join 1.1 什么是 Fork-Join    Java多线程的开发可以我们自己启用多线程,线程池,还可以使用forkjoin。forkjoin可以让我们不去了解诸如Thread、Runnable等相关的知识,只要遵循forkjoin的开发模式,就可以写出很好的多线程并发程序。    forkjoin采用的是分而治之。分而治之思想是:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。分而治之的策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为m个规模较小的子问题, 这些子问题互相独立且与原问题形式相同 ( 子问题相互之间有联系就会变为动态规范算法 ) ,递归地解这些子问题,然后将各子问题的解合并得到原问题的解,这种算法设计策略叫做分治法。用一张图来表示forkjoin原理。    我们可以了解一下计算机的十大经典算法: 快速排序、 堆排序、 归并排序 、二分查找、 BFPRT(线性查找)、DFS(深度优先搜索)、 BFS(广度优先搜索)、 Dijkstra、动态规划

悲观锁与乐观锁

这一生的挚爱 提交于 2020-03-11 07:33:51
1、悲观锁并发控制方案,就是在各种情况下都上锁,上锁之后,就只有一个线程可以操作这些内容了。在不同的情况下可以设置不同的锁,比如:行级锁,表级锁。 2、乐观锁并发控制方案,是不加锁的,写入的时候会判断当前数据的版本号跟es中的版本号是否相同,如果相同就直接写入;如果版本号不相同,说明数据已经被其他线程修改过了,此时该线程会从es中重新读取最新版本的数据,再次执行逻辑处理,然后重复以上流程。 ----------------------------------------------------------------------------------------------------------- 悲观锁与乐观锁的优缺点: 1、悲观锁的优点:方便,直接加锁,对应用程序来说,透明,不需要做额外的操作。 缺点:并发能力很低,同一时间,只能有一条线程操作数据。 2、乐观锁的优点:并发能力很高,不给数据加锁,可以大量线程并发操作。 缺点:麻烦,每次更新数据的时候,都要先对比版本号,然后可能需要重新加载数据,再次执行逻辑处理,再写;这个过程可能要重复很多次。 来源: https://www.cnblogs.com/qinjf/p/8460186.html

python 线程

微笑、不失礼 提交于 2020-03-11 06:53:06
创建线程: tsing=threading.Thread(target=sing,name="唱",args=(a,)) #创建的线程的目标:sing(执行sing函数),线程的名字为“唱“,主线程向子线程传递参数a(为元组类型) 获取当前线程的名字:threading.current_thread().name 来源: https://www.cnblogs.com/xkdn/p/12460160.html

Dubbo基本原理机制

|▌冷眼眸甩不掉的悲伤 提交于 2020-03-11 06:49:10
转自:http://blog.csdn.net/paul_wei2008/article/details/19355681 分布式服务框架: –高性能和透明化的RPC远程服务调用方案 –SOA服务治理方案 -Apache MINA 框架基于Reactor模型通信框架,基于TCP长连接 Dubbo缺省协议采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。 分析源代码,基本原理如下: client一个线程调用远程接口,生成一个唯一的ID(比如一段随机字符串,UUID等),Dubbo是使用AtomicLong从0开始累计数字的 将打包的方法调用信息(如调用的接口名称,方法名称,参数值列表等),和处理结果的回调对象callback,全部封装在一起,组成一个对象object 向专门存放调用信息的全局ConcurrentHashMap里面put(ID, object) 将ID和打包的方法调用信息封装成一对象connRequest,使用IoSession.write(connRequest)异步发送出去 当前线程再使用callback的get()方法试图获取远程返回的结果,在get()内部,则使用synchronized获取回调对象callback的锁, 再先检测是否已经获取到结果,如果没有,然后调用callback的wait(