自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

小生的博客

小生的博客

  • 博客(73)
  • 收藏
  • 关注

原创 I/O多路复用

一切的开始,都起源于这个 read 函数是操作系统提供的,而且是阻塞的,我们叫它阻塞 IO。为了破这个局,程序员在用户态通过多线程来防止主线程卡死。后来操作系统发现这个需求比较大,于是在操作系统层面提供了非阻塞的 read 函数,这样程序员就可以在一个线程内完成多个文件描述符的读取,这就是非阻塞 IO。但多个文件描述符的读取就需要遍历,当高并发场景越来越多时,用户态遍历的文件描述符也越来越多,相当于在 while 循环里进行了越来越多的系统调用。

2023-02-09 16:30:27 349 1

原创 JVM 线程本地分配缓存TLAB

从内存模型而不是垃圾收集的角度,对 Eden 区域继续进行划分,JVM 为每个线程分配了一个私有缓存区域,它包含在 Eden 空间内多线程同时分配内存时,使用 TLAB 可以避免一系列的非线程安全问题,同时还能提升内存分配的吞吐量,因此我们可以将这种内存分配方式称为快速分配策略。

2023-02-09 10:28:25 579

原创 G1垃圾回收器

在G1中,大对象的判断是超过一个Region大小的50%,按照每个Region大小为2MB来计算,只要对象超过了1MB,就会被放入到Humongous的Region中,如果一个对象太大,一个Region放不下,那么G1会寻找连续的H分区来存储,如果寻找不到连续的H区的话,就不得不启动 Full GC 了。识别被老年代对象指向的 Eden 中的对象,这些被指向的Eden中的对象被认为是存活的对象,找到老年代引用者对象后,更新老年代引用对象的引用地址,从eden更改为survivor的地址。

2023-02-08 16:00:58 804

原创 jvm三色标记法和读写屏障

三色标记算法是并发收集阶段的重要算法,它是描述追踪式回收器的一种有用的方法,利用它可以推演回收器的正确性。SATB,增量更新 g1 cms

2023-02-08 14:41:21 620

原创 记忆集(Remember Set)和卡表(Card Table)

这是一种"双向"的卡表结构(卡表是"我指向谁",这种结构还记录了"谁指向我")比原来的卡表实现起来更加复杂,同时由于Region数量比传统收集器的分代数量明显要多得多,因此G1收集器要比其他的传统垃圾收集器有着更高的内存占用负担。比如在进行Minor GC的时候,我们便不用扫描整个老年代对象,而是在卡表中寻求脏卡,并将脏卡中的对象加入到Minor GC的GC Roots里(Minor GC时JVM将从脏卡中的对象查找,作为GC Roots)。因此,在更新引用的同时,我们又会设置引用所在的卡的标识位。记忆集

2023-02-07 17:33:59 1169

原创 强引用,软引用,弱引用,虚引用

Java中4种引用的级别和强度由高到低依次为:强引用 -> 软引用 -> 弱引用 -> 虚引用引用类型被垃圾回收时间用途生存时间强引用从来不会对象的一般状态JVM停止运行时终止软引用当内存不足时对象缓存内存不足时终止弱引用正常垃圾回收时对象缓存垃圾回收后终止虚引用正常垃圾回收时跟踪对象的垃圾回收垃圾回收后终止。

2023-02-02 17:19:32 261

原创 字符串不可变

字符串被广泛用于许多java类的参数,如网络连接、打开文件、字符串等都不是一成不变的,一个连接或文件将被改变,这可能导致严重的安全威胁。这时当初始化s2时发现常量池中已经存在了"abc"就会直接引用这个字符串,不需要重新创建字符串对象了。不可变意味着修改性能差,这也是为什么在频繁修改字符串的时候要使用StringBuilder和StringBuffer的原因。如果字符串是可变的,用一个引用更改字符串将导致其他引用的值错误。字符串常量池就是一个存储着各种字符串的一个常量,简单理解就是一些字符串对象的缓存池。

2023-02-01 17:07:15 232 1

原创 使用命令行调用dubbo服务

今天排查线上问题需调用其他服务,公司项目本地没办法访问预发环境,最终在预发环境服务器通过命令调用其他服务方法。未来有时间可以基于这些命令封装成一个dubbo服务的管理工具。一.使用telnet命令连接dubbo服务telnet ip 端口二.查看已注册服务连接好服务后使用ls命令可以查看已注册服务。ls 注册服务可查看服务中的方法ls 显示服务列表。ls -l 显示服务详细...

2020-04-16 19:51:29 1065

原创 基于dubbo实现异步调用

基于dubbo实现异步调用增加consumer配置这种方式很简单,只需要在服务引用时增加dubbo:method配置即可,如下所示,其中name为需要异步调用的方法名,async表示是否启用异步调用。<dubbo:reference id="asyncService" check="false" interface="com.alibaba.dubbo.demo.AsyncServic...

2020-03-17 17:34:54 820

原创 面试

Nginx 有哪些优点?跨平台、配置简单。非阻塞、高并发连接处理 2-3 万并发连接数,官方监测能支持 5 万并发。内存消耗小开启 10 个 Nginx 才占 150M 内存。成本低廉,且开源。稳定性高,宕机的概率非常小。Nginx 有哪些负载均衡策略?负载均衡,即是代理服务器将接收的请求均衡的分发到各服务器中。轮询(默认)round_robin每个...

2020-03-12 16:53:24 285

原创 rocketMQ定时和延时消息

定时消息和延时消息适用于以下一些场景:消息生产和消费有时间窗口要求:比如在电商交易中超时未支付关闭订单的场景,在订单创建时会发送一条延时消息。这条消息将会在 30 分钟以后投递给消费者,消费者收到此消息后需要判断对应的订单是否已完成支付。如支付未完成,则关闭订单。如已完成支付则忽略。通过消息触发一些定时任务,比如在某一固定时间点向用户发送提醒消息。定时消息 // 定时消息,单位毫秒(ms)...

2020-03-12 15:36:31 1763 1

原创 将一个整数随机分成n份,且每份不少于m

首先如何将一个整数随机分成n份。这个问题转化成:假设有sum个人排成一排,往这sum-1个空隙里插入n-1个纸版,把他们分成n部分。所以解决办法就是随机依次选n-1个位置。所以随机抽取n-1个小于sum的数作为要插入的空隙。然后这群人会被分成n段,也就是n个随机数。步骤:先随机抽取n-1个小于sum的数组成数组,并在数组头部加0,尾部加sum;将数组进行升序排序;每两个相邻元素数之间的...

2020-03-12 15:12:53 6454

原创 条件队列实现生产者消费者

public static void main(String [] args){ Say say = new Say(); new Thread(new Runnable() { @Override public void run() { while (true) { ...

2020-03-12 12:36:00 165

原创 两个线程交替打印

通过条件队列实现public class Test { public static void main(String [] args){ Say say = new Say(); new Thread(new Runnable() { @Override public void run() { ...

2020-03-12 12:02:32 167

原创 TCP和UDP

TCP和UDP属于数据传输协议TCP三次握手TCP 的建立连接称为三次握手,可以简单理解为下面这种情况A:您好,我是 AB:您好 A,我是 BA:您好 B 建立连接TCP 的三次握手除了建立连接外,主要还是为了沟通 TCP 包的序号问题。A 告诉 B,我发起的包的序号是从哪个号开始的,B 同样也告诉 A,B 发起的 包的序号是从哪个号开始的。四次挥手说完建立连接,再说下断...

2020-03-11 18:42:31 119

原创 常用垃圾回收器

前常用的垃圾回收器有7个,按照工作的内存区间的不同,可以分为3个新生代收集器和3个年老代收集器。G1比较特殊不分代Serial(新生代串行收集器)使用复制算法的垃圾回收器,只能用于新生代。Serial回收器使用单线程进行垃圾回收。在 HotSpot 虚拟机中,使用-XX:+UseSerialGC 参数可以指定使用Serial(新生代串行收集器)+ Serial Old(老年代串行收集器)...

2020-03-11 18:00:37 262

原创 常用算法讲解及java实现

二分查找/**二分查找又称折半查找,它是一种效率较高的查找方法。  【二分查找要求】:1.必须采用顺序存储结构 2.必须按关键字大小有序排列。/** * * 二分查找算法 * * * * @param srcArray * 有序数组 * * @param des * 查找元素 * * @return des的数组...

2020-03-11 11:21:16 265

原创 paxos算法

paxos算法Paxos算法及变种算法在分布式系统中应用广泛。基于Paxos算法的变种有:ZAB、RaftPaxos算法解决的问题是在一个可能发生消息可能会延迟、丢失、重复的分布式系统中如何就某个值达成一致,保证不论发生以上任何异常,都不会破坏决议的一致性。角色提议者(proposer): 进行提议的角色批准者(acceptor): 通过提议的角色学习者(learner): 感知(...

2020-03-10 17:31:54 333

原创 heapanalyzer分析内存

heapAnalyzer使用教程heapAnalyzer是ibm的一个内存分析工具,当服务器内存负载出现问题时可以生成堆的dump文件,然后通过heapanalyzer可以堆dump文件进行分析,分析内存泄漏对象,或者那些对象占用大量内存。jmap命令:例如jvm进程号为3331jmap -heap 3331:查看java 堆(heap)使用情况jmap -histo 3331:查...

2020-03-07 10:11:43 793

原创 分布式事物

主流的分布式事物实现方式两阶段提交两阶段提交,有一个事务管理器的概念,负责协调多个数据库(资源管理器)的事务,事务管理器先问问各个数据库你准备好了吗?如果每个数据库都回复 ok,那么就正式提交事务,在各个数据库上执行操作;如果任何其中一个数据库回答不 ok,那么就回滚事务。第一阶段询问,第二阶段执行。补偿机制 TCC其实就是程序员自己写代码维护事物回滚和补偿,补偿机制说简单点就是在代码里...

2020-03-07 09:28:58 210

原创 三种分布式锁的实现方式对比

基于数据库实现加锁,或类似redis记录数据。性能不好不用!基于Redis实现这是比较常用的一种实现方式。通过setnx可以存入key,如果存入key成功返回1,如果存入的key已经存在了,返回0.如此可以判断key存在说明已经有节点调用,不存在说明没有节点调用。基于ZooKeeper的实现多个客户端(jvm),同时在zk上创建相同的一个临时节点,因为临时节点路径是保证唯一,只要谁能够...

2020-03-07 08:48:20 248

原创 高并发场景下的库存更新

在高并发的情况下,肯定不能高频率的去读写数据库,会严重造成性能问题的必须使用缓存,将需要秒杀的商品放入缓存中,并使用锁来处理其并发情况。当接到用户秒杀提交订单的情况下,先将商品数量递减(加锁/解锁)后再进行其他方面的处理,处理失败在将数据递增1(加锁/解锁),否则表示交易成功。当商品数量递减到0时,表示商品秒杀完毕,拒绝其他用户的请求。肯定不能直接操作数据库的,会挂的。直接读库写库对数...

2020-03-07 08:05:16 2104 1

原创 java并发编程(十三)CAS与原子变量

锁的劣势使用锁有以下的缺点:如果线程持有锁而延迟,会导致其他的线程的等待。高优先级的线程阻塞,而低优先级的线程持有锁造成 优先级反转(priority inversion)。如果持有锁的线程被永久地阻塞,所有等待这个锁的线程就无法执行下去,造成 死锁(dead lock)。为了避免这些问题,我们更倾向于非阻塞算法来保证同步。比较交换(CAS)CAS的含义是:“我认为V...

2020-03-06 18:33:02 109

原创 java并发编程(十二)自定义同步工具

条件队列条件队列可以使得一组线程(称之为等待线程集合)能够通过某种方式来等待特定的条件变成真。如每个Java对象都可以作为一个锁,每个对象同样可以作为一个条件队列,这就是java内部的条件队列。Object中的wait、notify和notifyAll方法就构成了内部条件队列的API。Object.wait会自动释放锁,并请求操作系统挂起当前线程,从而使其他线程能够获得这个锁并且修改对象的...

2020-03-06 17:17:49 144

原创 java并发编程(十一)显式锁

Lock与ReentrantLockLock接口与内置锁机制不同,Lock提供了一种可轮询,可定时,可中断的锁。且所有的加锁解锁操作都是显式的。ReentrantLock是Lock接口的默认实现类。Lock接口定义的方法如下所示:void lock() 获取锁。如果锁不可用,出于线程调度目的,将禁用当前线程,并且在获得锁之前,该线程将一直处于休眠状态void lockInterrupti...

2020-03-06 11:47:06 119

原创 java并发编程(十)性能与可伸缩行

线程的最主要目的是提高程序的运行性能要想通过并发来获得更好的性能,需要努力做好两件事情:更有效地利用现有处理资源,以及在出现新的处理资源时使程序尽可能地利用这些新资源。从性能监视的视角来看,CPU需要尽可能保持忙碌状态。这也就是程序的性能与可伸缩性。线程引入的开销尽管使用多个线程的目标是提升整体性能,但与单线程的方法相比,使用多个线程总会引人一些额外的性能开销。造成这些开销的操作包括:线程之...

2020-03-05 17:11:40 93

原创 java并发编程(九)活跃性危险

线程的活跃性危险主要包括死锁,饥饿和活锁。死锁锁顺序死锁:两个线程试图以不同的顺序来获得相同的锁。比如一个线程先获取a锁后获取b锁,另一个线程先获取b锁后获取a锁。如果两个按照相同的顺序来请求锁(在相同时间请求a锁,在相同时间获取b锁),那么没问题,但是如果第一个线程获取了a锁的同时另一个线程获取了b锁,当两个线程分别获取第二个锁时会发现各自需要的锁都被对方持有了,也就发生了死锁。为了避...

2020-03-05 14:55:13 142

原创 java并发编程(八)线程池

任务与执行策略之间的隐形耦合Executors为我们提供了相当灵活的执行策略来生成线程池,但是这些线程池的执行策略并不能满足所有的任务。对于这些任务我们需要手动的指定执行策略来执行任务。这些任务包括以下几种:依赖性任务大多数任务都是相互独立的,这种情况下我们可以任意的改变线程池的大小和配置。但是如果线程池内的任务存在相互间的依赖,那么我们就必须小心的维护执行策略。如果执行策略不正确可能...

2020-03-05 11:17:54 262

原创 java并发编程(七)线程的取消与关闭

中断要使任务和线程安全、快速、可靠的停止下来并不是一件容易的事情。java没有提供任何机制来安全的终止线程。但它提供了中断(Interruption),这是一种协作机制能够使一个线程终止另一个线程的当前工作。通常,中断是实现取消的最合理方式。中断是礼貌地请求另一个线程在它愿意并且方便的时候停止它正在做的事情。有些方法,例如 Thread.sleep(),wait,jion很认真地对待这样的...

2020-03-04 18:20:46 237

原创 java并发编程(六)任务执行

大多数并发应用都是围绕任务执行来构造的,任务通常是一些抽象且离散的工作单元。在线程中执行任务在线程中执行任务大致分为两种情况。一种是单线程串行化执行任务,另一种是为每一个任务创建线程来执行。串行化执行任务在单线程中串行的执行各项任务是执行任务最简单的策略。串行化执行任务的缺点是无法提供高吞吐率以及快速响应。但是串行化执行任务的优点是更加的简单和安全。所以当任务比较少且执行时间很长,简...

2020-03-04 15:53:36 186

原创 java并发编程(五)java常用的并发编程工具类

同步容器类同步容器类包括vector和HashTable,这些同步类都是使用synchronizedXXX等工厂方法创建的,简单粗暴的将整个对象锁起来,效率很差。现在大多已经被弃用了。并发容器类并发容器类主要包括concurrentHashMap和copyOnWriteList。ConcurrentHashMapConcurrentHashMap是由Segment数组结构和HashEnt...

2020-03-04 12:07:40 166

原创 java并发编程(四)如何设计一个线程安全的类

设计线程安全的类设计线程安全类的三个基本要素:找出构成对象的所有变量找出所有约束所有变量的不变性条件,简单说就是变量的正确限制。一个变量在整个类的逻辑中对其有什么样的限制,比如必须大于0等等条件。建立对象的并发状态下的访问管理策略。实例封闭封装简化了线程安全类的实现过程,提供了一种实例封闭机制。当一个对象被封装在另一个对象中时,那么对这个对象的访问全部由另一个对象来调用。对这个对...

2020-03-03 15:29:25 506

原创 java并发编程(三)对象共享

可见性很多人认为synchronized只能用于实现原子性或者确定临界区,忽视了它另一个重要的作用,确保内存可见性。每个线程都有自己的工作内存。线程对变量的所有操作都必须在工作内存中进行,而不能直接对主存进行操作。并且每个线程不能访问其他线程的工作内存。所以在写线程没有将工作内存的数据同步到主存前其他线程是无法看先写入的值的。指令重排序就是在不影响程序逻辑结果时为了充分利用cpu指令的执行顺...

2020-03-03 11:19:27 153

原创 java并发编程(二)线程的安全性

线程安全的核心在于对状态的访问操作,特别是共享状态和可变状态。共享意味着可以同时被多个线程访问,可变意味着生命周期内可以发生变化。要是对象是线程安全的就要使用同步机制来保证对对象状态的访问。java中主要的同步机制 包括关键字synchronized独占锁,Lock显式锁,原子变量(amoticInteger等)等,当然也包括volatile类型变量,注意volatile类型变量并不能保证数据...

2020-03-02 16:49:08 140

原创 java并发编程详解(一)初步了解线程

线程线程与进程最大的区别就是 每个进程都独立分配着独立的资源包括内存等,进程之间通过粗力度的通信交换数据。而线程则是共享进程范围内的资源。那个线程拥有各自的程序计数器,局部变量等。因此线程也被称为轻量级进程。在大多数操作系统中线程都是基本的调度单位,正因为如此如果程序中只有一个线程,那么最多同时只能在一个处理器上运行,但是现在大部分都是多核处理器,这样单线程同时只能使用部分cpu资源。多线程可...

2020-03-02 11:21:19 112

原创 elasticsearch实现商品搜索

elasticsearch实现商品搜索安装es安装rocketmq数据同步

2020-03-01 15:20:06 2549

原创 rocketmq入门

RocketMQ简介1.RocketMQ是一款分布式、队列模型的消息中间件,是阿里巴巴集团自主研发的专业消息中间件,借鉴参考了JMS规范的MQ实现,更参考了优秀的开源消息中间件KAFKA,实现了业务消峰、分布式事务的优秀框架。2.其底层代码编写清晰优秀,采用Netty NIO框架进行数据通信3.摒弃了Zookeeper,内部使用更轻量级的NameServer进行网络路由,提高服务性能,并且支...

2020-03-01 11:20:56 287

原创 springboot的ApplicationRunner实现应用启动后初始化操作

springboot的ApplicationRunner实现应用启动后初始化操作在日常项目中可能会遇到一些需要在项目启动完成后进行的一些初始化操作。实现:定义一个类TestApplicationRunner实现ApplicationRunner接口,然后重写ApplicationRunner接口的run方法,代码如下@Component//如果有多个runner需要指定一些顺序@Ord...

2020-02-29 17:25:14 1297 1

原创 elasticsearch入门

elasticsearch入门Elasticsearch是一个开源的分布式、RESTful 风格的搜索和数据分析引擎,它的底层是开源库Apache Lucene。  Lucene只是一个库。想要使用它,你必须使用Java来作为开发语言并将其直接集成到你的应用中,更糟糕的是,Lucene非常复杂,你需要深入了解检索的相关知识来理解它是如何工作的。Elasticsearch也使用Java开发并使用...

2020-02-29 16:19:49 167

原创 退款编号微信处理失败后,需重新生成退款编号

今天遇到一个问题,项目在处理微信退款失败的订单发起重新退款时会报退款编号已经被使用。查官方文档发现退款编号微信处理失败后,需重新生成退款编号。原有的退款编号不能继续使用。...

2020-02-29 11:20:05 527

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除