Netty分布式从recycler对象回收站获取对象过程剖析
作者:向南是个万人迷 发布时间:2021-08-12 06:45:48
前文传送门:Netty分布式高性能工具类recycler的使用及创建
从对象回收站中获取对象
我们回顾上一小节demo的main方法中
从回收站获取对象
public static void main(String[] args){
User user1 = RECYCLER.get();
user1.recycle();
User user2 = RECYCLER.get();
user2.recycle();
System.out.println(user1==user2);
}
这个通过Recycler的get方法获取对象, 我们跟到get方法中:
public final T get() {
if (maxCapacityPerThread == 0) {
return newObject((Handle<T>) NOOP_HANDLE);
}
Stack<T> stack = threadLocal.get();
DefaultHandle<T> handle = stack.pop();
if (handle == null) {
handle = stack.newHandle();
handle.value = newObject(handle);
}
return (T) handle.value;
}
首先判断maxCapacityPerThread是否为0, maxCapacityPerThread代表stack最多能缓存多少个对象, 如果缓存0个, 说明对象将一个都不会回收
这个通过调用newObject创建一个对象, 并传入一个NOOP_HANDLE, NOOP_HANDLE是一个handle, 我们看其定义:
private static final Handle NOOP_HANDLE = new Handle() {
@Override
public void recycle(Object object) {
}
};
这里的recycle方法是一个空实现, 代表不进行任何对象回收
回到get方法中
我们看第二步
Stack<T> stack = threadLocal.get();
这里通过FastThreadLocal对象拿到当前线程的stack, 有关FastThreadLocal获取对象的逻辑之前小节剖析过, 这里不再赘述
获取stack之后, 从stack中pop出一个handle, 这个handle做用我们稍后分析
如果取出的对象为null, 说明当前回收站内没有任何对象, 通常第一次执行到这里对象还没回收, 这里就会是null, 这样则会通过stack.newHandle()创建一个handle
创建出来的handle的value属性, 通过我们重写的newObject方法进行赋值, 也就是我们demo中的user
我们跟进newHandle方法
DefaultHandle<T> newHandle() {
return new DefaultHandle<T>(this);
}
这里创建一个DefaultHandle对象, 并传入this, 这里的this是当前stack
跟到DefaultHandle的构造方法中:
DefaultHandle(Stack<?> stack) {
this.stack = stack;
}
这里初始化了stack属性
DefaultHandle中还有个value的成员变量
private Object value;
这里的value就用来绑定回收的对象本身
回到get方法中:
分析handle, 我们回到上一步:
DefaultHandle<T> handle = stack.pop();
我们分析从stack中弹出一个handle的逻辑
跟到pop方法中
DefaultHandle<T> pop() {
int size = this.size;
if (size == 0) {
if (!scavenge()) {
return null;
}
size = this.size;
}
size --;
DefaultHandle ret = elements[size];
elements[size] = null;
if (ret.lastRecycledId != ret.recycleId) {
throw new IllegalStateException("recycled multiple times");
}
ret.recycleId = 0;
ret.lastRecycledId = 0;
this.size = size;
return ret;
}
首先拿到size, size表示当前stack的对象数
如果size为0, 则调用scavenge方法, 这个方法是异线程回收对象的方法, 我们放在之后的小节进行分析
size大于零, 则size进行自减, 代表取出一个元素
然后通过size的数组下标的方式将handle取出
之后将当前下标设置为null
最后将属性recycleId, lastRecycledId, size进行赋值
recycleId和lastRecycledId我们会在之后的小节进行分析
回到get方法中:
public final T get() {
if (maxCapacityPerThread == 0) {
return newObject((Handle<T>) NOOP_HANDLE);
}
Stack<T> stack = threadLocal.get();
DefaultHandle<T> handle = stack.pop();
if (handle == null) {
handle = stack.newHandle();
handle.value = newObject(handle);
}
return (T) handle.value;
}
无论是从stack中弹出的handle, 还是创建的handle, 最后都要通过handle.value拿到我们实际使用的对象
来源:https://www.cnblogs.com/xiangnan6122/p/10208952.html
猜你喜欢
- 坑出现的环境一般情况下切割字符串会使用split或者StringTokenizer,如下代码String s = ",,o,,&q
- @RequestBody搭配@Data的坑如果用@Data修饰实体类,里面的属性最好不要用连续几个相同字母,如果用千万别用大写。比如下面这个
- 百度百科说法:Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务
- Android 解决TextView排版参差不齐的问题在app中,展示数据时,里面有汉字、数字、特殊字符时,由于全角、半角问题导
- Random类 (java.util) Ran
- 简单介绍如果把单链表的最后一个节点的指针指向链表头部,而不是指向NULL,那么就构成了一个单向循环链表,通俗讲就是让尾节点指向头结点。单向环
- 1. 概述官方JavaDocsApi: javax.swing.JList JList,列表框。JList 以列表的形式展示多个选项,允许用
- 一、常用操作NextDouble():返回0-1.0之间的随机数Next():返回非负随机整数(0-216)Next(i):返回一个小于i的
- 本文实例讲述了Java基于动态规划法实现求最长公共子序列及最长公共子字符串。分享给大家供大家参考,具体如下:动态规划法经常会遇到复杂问题不能
- 前言在做项目的时候,如果项目是前后分离的,后端一定要和前端或者是移动端对接接口,那么问题来了,接口是不是要自己写给他们看,一般的会采用Exc
- 一、正则表达式去除代码行号作为开发人员,我们经常从网上复制一些代码,有些时候复制的代码前面是带有行号,如:MyEclipse本身自带有查找替
- 简介反射是Java编程语言中的一个特性。它允许执行的Java程序检查或 操作 自身,并操作程序的内部属性。例如,Java类可以获取其所有成员
- 在使用EL时,其实EL是先看标识符是否是其隐式对象之一,如果不是,才从四个域(page、request、session、applicatio
- 问题场景之前写过一篇文章: 2.@JvmOverloads快捷实现函数重载, 借助于Kotlin的默认参数+@JvmOverloads简化自
- 一、原因:forceclose,意为强行关闭,当前应用程序发生了冲突。NullPointExection(空指针),IndexOutOfBo
- 前言在我们做后端服务Dao层开发,特别是大数据批量插入的时候,这时候普通的ORM框架(Mybatis、hibernate、JPA)就无法满足
- 这篇文章主要介绍了JAVA实现账户取款和存款操作,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以
- JAVA IDEA 打开assert 设置概念(此处为借鉴前辈们的讲解)断言(Assertion)是Java中一条语句,包含一个布尔表达式,
- 介绍try-with-resources是Java中的环绕语句之一,旨在减轻开发人员释放try块中使用的资源的义务。它最初在Java 7中引
- 前言对于初学者们来说,刚开始编写Java代码时,会遇到很多困难,下面来说一个比较常见的错误,如下:初学者一般都是从Hello,World开始