多线程1
什么是线程和进程?何为进程?进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。
在 Java 中,当我们启动 main 函数时其实就是启动了一个 JVM 的进程,而 main 函数所在的线程就是这个进程中的一个线程,也称主线程。
如下图所示,在 windows 中通过查看任务管理器的方式,我们就可以清楚看到 window 当前运行的进程(.exe 文件的运行)。
何为线程?线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享进程的堆和方法区资源,但每个线程有自己的程序计数器、虚拟机栈和本地方法栈,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。
Java 程序天生就是多线程程序,我们可以通过 JMX 来看一下一个普通的 Java 程序有哪些线程,代码如下。
123456789101112public class MultiThread { public static ...
JOL使用
查看普通java对象的内部布局工具JOL(JAVA OBJECT LAYOUT)
使用此工具可以查看new出来的一个java对象的内部布局,以及一个普通的java对象占用多少字节。
导入依赖或者jar包
可以选择导入pom依赖
12345678<!-- https://mvnrepository.com/artifact/org.openjdk.jol/jol-core --><dependency> <groupId>org.openjdk.jol</groupId> <artifactId>jol-core</artifactId> <version>0.9</version> <scope>provided</scope></dependency>
可以使用jar包
地址:https://mvnrepository.com/artifact/org.openjdk.jol/jol-core/0.9
使用12345 ...
ReentrantLock底层实现原理
前言Java中的大部分同步类(Lock、Semaphore、ReentrantLock等)都是基于AbstractQueuedSynchronizer(简称为AQS)实现的。AQS是一种提供了原子式管理同步状态、阻塞和唤醒线程功能以及队列模型的简单框架。本文会从应用层逐渐深入到原理层,并通过ReentrantLock的基本特性和ReentrantLock与AQS的关联,来深入解读AQS相关独占锁的知识点,同时采取问答的模式来帮助大家理解AQS。由于篇幅原因,本篇文章主要阐述AQS中独占锁的逻辑和Sync Queue,不讲述包含共享锁和Condition Queue的部分(本篇文章核心为AQS原理剖析,只是简单介绍了ReentrantLock,感兴趣同学可以阅读一下ReentrantLock的源码)。
1 ReentrantLock1.1 ReentrantLock特性概览ReentrantLock意思为可重入锁,指的是一个线程能够对一个临界资源重复加锁。为了帮助大家更好地理解ReentrantLock的特性,我们先将ReentrantLock跟常用的Synchronized进行比较,其 ...
LongAdder和Sync和Atomic
自己在项目中使用 CompletableFuture 比较多,看到很多开源框架中也大量使用到了 CompletableFuture 。
因此,专门写一篇文章来介绍这个 Java 8 才被引入的一个非常有用的用于异步编程的类。
简单介绍CompletableFuture 同时实现了 Future 和 CompletionStage 接口。
12public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {}
CompletableFuture 除了提供了更为好用和强大的 Future 特性之外,还提供了函数式编程的能力。
Future 接口有 5 个方法:
boolean cancel(boolean mayInterruptIfRunning) :尝试取消执行任务。
boolean isCancelled() :判断任务是否被取消。
boolean isDone() : 判断任务是否已经被执行完成。
get() :等待任务执行完成并获取 ...
ThreadLocal原理
前言本文来自一枝花算不算浪漫投稿, 原文地址:https://juejin.im/post/5eacc1c75188256d976df748。
全文共 10000+字,31 张图,这篇文章同样耗费了不少的时间和精力才创作完成,原创不易,请大家点点关注+在看,感谢。
对于ThreadLocal,大家的第一反应可能是很简单呀,线程的变量副本,每个线程隔离。那这里有几个问题大家可以思考一下:
ThreadLocal的 key 是弱引用,那么在 ThreadLocal.get()的时候,发生GC之后,key 是否为null?
ThreadLocal中ThreadLocalMap的数据结构?
ThreadLocalMap的Hash 算法?
ThreadLocalMap中Hash 冲突如何解决?
ThreadLocalMap的扩容机制?
ThreadLocalMap中过期 key 的清理机制?探测式清理和启发式清理流程?
ThreadLocalMap.set()方法实现原理?
ThreadLocalMap.get()方法实现原理?
项目中ThreadLocal使用情况?遇到的坑?
……
上述 ...
markdown之数学公式
[转] Markdown 中的常用 LaTex 数学公式 - 连玉君的文章 - 知乎 https://zhuanlan.zhihu.com/p/95886235
作者:**毒逆天**出处:**https://www.cnblogs.com/dotnetcrazy** 打赏:18i4JpL6g54yAPAefdtgqwRrZ43YJwAV5z 本文版权归作者和博客园共有。欢迎转载,但必须保留此段声明,且在文章页面明显位置给出原文连接!
1.样式系列1.1.换行\\、空格\:1$换行\\萌萌哒\:小明$
1.2.居中$$\**$$1$$萌萌哒$$
1.3.加粗(mathbf)、斜体(mathit)123$\mathbf{萌萌哒}$$\mathit{小明}$
1.4.大小123456789101112131415$\tiny 萌萌哒$$\scriptsize 萌萌哒$$\small 萌萌哒$$\normalsize 萌萌哒(正常)$$\large 萌萌哒$$\Large 萌萌哒$$\huge 萌萌哒$$\Huge 萌萌哒$
...
百万数据快速插入数据库
https://blog.csdn.net/zl1zl2zl3/article/details/105007492?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-5.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-5.control
前言一直有一种说法:批量插入大量数据到MySQL数据库,不要使用Mybatis、Hibernate之类的ORM框架,原因一般都是说性能不好,至于为什么不好好像没几个人能讲清楚的。
批量插入大量数据最优的方式是什么?网上也是众说纷纭。不如自己动手测试一下吧!
场景介绍前几天公司项目进行压力测试,测试某个功能在大数据量(千万级)的情况下是否能够正常运行,可是项目还没有正式上线运营,数据库里只有少量开发时用的假数据。
没有数据怎么测试啊?这可愁坏 ...
CAS
CAS:compar and swap,是一种自旋锁
属于乐观锁,是解决多线程并行情况下使用锁造成性能损耗的一种机制,CAS操作包含三个操作数——内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无论哪种情况,它都会在CAS指令之前返回该位置的值。CAS有效地说明了“我认为位置V应该包含值A;如果包含该值,则将B放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。
ABA问题加入有三个线程,线程A读取内存中数据为0,然后i++,线程B读取内存中数据位0,然后i++,线程A运行比较慢,线程B把1写入内存,然后有一个线程C,读取内存中数据位1,进行i–操作,然后把0写入内存,这个时候线程A才运行完毕,然后读取内存中数据位0,认为没有发生修改,则把1写入数据。
这个时候线程A认为内存中0的数据没有修改,写入内存了,但是这个数据确实发生了修改。这就是ABA问题
解决方案:
不管
这个一个值,我不在在乎,你想改就改,我要的是最终的值
添加版本
这是一个引用,应用的地址没有发生改 ...
AQS详解
AQS 对资源的共享方式AQS 定义两种资源共享方式
1)Exclusive(独占)
只有一个线程能执行,如 ReentrantLock。又可分为公平锁和非公平锁,ReentrantLock 同时支持两种锁,下面以 ReentrantLock 对这两种锁的定义做介绍:
公平锁 :按照线程在队列中的排队顺序,先到者先拿到锁
非公平锁 :当线程要获取锁时,先通过两次 CAS 操作去抢锁,如果没抢到,当前线程再加入到队列中等待唤醒。
说明:下面这部分关于 ReentrantLock 源代码内容节选自:https://www.javadoop.com/post/AbstractQueuedSynchronizer-2 ,这是一篇很不错文章,推荐阅读。
下面来看 ReentrantLock 中相关的源代码:
ReentrantLock 默认采用非公平锁,因为考虑获得更好的性能,通过 boolean 来决定是否用公平锁(传入 true 用公平锁)。
123456789/** Synchronizer providing all implementation mechanics */priv ...
LongAdder和Sync和Atomic
LongAdder和Sync和AtomicLongAdder内部使用了分段锁,将单一的CAS操作分散为对数组Cells中多个元祖的CAS
在高并发(千、万级并发以上)LongAdder的效率大于Atomic大于synchronized
AtomicAtomic 原子类介绍Atomic 翻译成中文是原子的意思。在化学上,我们知道原子是构成一般物质的最小单位,在化学反应中是不可分割的。在我们这里 Atomic 是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰。
所以,所谓原子类说简单点就是具有原子/原子操作特征的类。
并发包 java.util.concurrent 的原子类都存放在java.util.concurrent.atomic下,如下图所示。
根据操作的数据类型,可以将 JUC 包中的原子类分为 4 类
基本类型
使用原子的方式更新基本类型
AtomicInteger:整型原子类
AtomicLong:长整型原子类
AtomicBoolean :布尔型原子类
数组类型
使用原子的方式更新数组里的某个元素
AtomicInte ...
shell安装re
yum install -y lrzsz
sz aaa.txt 将aaa.txt下载到本地
rz 直接输入此命令会弹出对话框要求选择文件
(1)安装JDK
1、将jdk-8u131-linux-x64.rpm通过WinSCP上传到虚拟机中2、安装JDK:rpm -ivh jdk-8u131-linux-x64.rpm3、配置jdk相关的环境变量vi .bashrcexport JAVA_HOME=/usr/java/latestexport PATH=$PATH:$JAVA_HOME/binsource .bashrc4、测试jdk安装是否成功:java -version
前端编译器和后端编译器
本文章转载于:https://blog.csdn.net/qq_20009015/article/details/105190415
前端编译器:将java文件编译成class文件的编译器。java很多提高效率和友好度的语法糖都是依赖前端编译器实现的。javac就是一个典型的前端编译器。
执行过程如下:
准备阶段:初始化插入式注解处理器
解析与填充符号表阶段:词法 语法分析,将源代码转变为标记集合,构建抽象语法树填充符号表,产生符号地址和符号信息。
插入式注解处理器的执行阶段:会影响javac的行为,比如说添加一些编译期的校验等。
分析与字节码的生成:检查静态信息,数据流检查,解语法糖,字节码生成
词法解析:将源代码的字符流转为标记(token)集合的过程,token是编译时的最小单位,关键字 变量名 运算符等都可以作为标记。
语法分析:根据标记序列构造抽象语法树,抽象语法树是一种描述程序代码语法结构的树形表示,树的每一个节点代表程序代码中的一个语法结构,比如说包,类型,修饰符,运算符等。
生成语法树之后,后续的操作都是对语法树进行操作。
填充符号表:符号表是一组符号地址和符 ...
jvm中对象的内存布局
对象的创建、内存布局和访问定位1. 对象创建
在开发使用时,创建 Java 对象仅仅只是是通过关键字new:
1A a = new A();
可是 Java对象在虚拟机中创建则是相对复杂。今天,我将详解Java对象在虚拟机中的创建过程
限于普通对象,不包括数组和Class对象等
1.1 创建过程当遇到关键字new指令时,Java对象创建过程便开始,整个过程如下:
Java对象创建过程
下面我将对每个步骤进行讲解。
步骤1:类加载检查
检查 该new指令的参数 是否能在 常量池中 定位到一个类的符号引用
检查 该类符号引用 代表的类是否已被加载、解析和初始化过
如果没有,需要先执行相应的类加载过程
关于类加载请看文章:
步骤2:为对象分配内存
虚拟机将为对象分配内存,即把一块确定大小的内存从 Java 堆中划分出来
对象所需内存的大小在类加载完成后便可完全确定
关于分配内存,此处主要讲解内存分配方式
内存分配 根据 Java堆内存是否绝对规整 分为两种方式:指针碰撞 & 空闲列表
Java堆内存 规整:已使用的内存在一边,未使用内存在另一边 ...
lua基础教程1-环境安装
什么是luaLua 是由巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组于1993年开发的一种轻量、小巧的脚本语言,用标准 C 语言编写,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
官网:http://www.lua.org/
Redis 在 2.6 版本中推出了脚本功能,允许开发者将 Lua 语言编写的脚本传到 Redis 中执行。使用 Lua 脚本的优点有如下几点:
减少网络开销:本来需要多次请求的操作,可以一次请求完成,从而节约网络开销;
原子操作:Redis 会将整个脚本作为一个整体执行,中间不会执行其它命令;
复用:客户端发送的脚本会存储在 Redis 中,从而实现脚本的复用。
安装基础lua环境安装lua环境下载github项目地址:https://github.com/rjpcomputing/luaforwindows/releases
github下载地址:https://github.com/rjpcomputing/luaforwin ...
lua基础教程2-基础语法
hello world1print("hello world!")
推荐菜鸟教程或者W3Cschool
https://www.w3cschool.cn/lua/lua-basic-syntax.html
基本语法交互式编程123> print("Hello World!")Hello World!>
脚本式编程123#!/usr/local/bin/luaprint("Hello World!")
注释单行注释两个减号是单行注释:
1--
多行注释1234--[[ 多行注释 多行注释 --]]
标识符Lua 标示符用于定义一个变量,函数获取其他用户定义的项。标示符以一个字母 A 到 Z 或 a 到 z 或下划线 _ 开头后加上0个或多个字母,下划线,数字(0到9)。
最好不要使用下划线加大写字母的标示符,因为Lua的保留字也是这样的。
Lua 不允许使用特殊字符如 @, $, 和 % 来定义标示符。 Lua 是一个区分大小写的编程语言。因此在 Lua 中 W3c 与 w3c 是两个不同的标示符 ...