java.lang.ref.Reference<T>_weixin_34383618的博客-程序员宝宝

技术标签: java  

//看之前先要知道java里面的四种引用。
package
com.zby.ref; import sun.misc.Cleaner; /** * 引用对象的抽象基础类。这个类定义了所有引用对象的公共操作。因为引用对象在跟垃圾收集器紧密合作中被实现,所以这个类不能被引用对象直接继承。 * * @author zhoubaiyun * * @param <T> */ public abstract class Reference<T> { /* * 一个引用实例是在这四个可能的内部状态之一。 * * 活跃状态:服从于垃圾处理器的特别处理。有时在收集器检测到可达到的引用对象已经改变成为适当的状态,收集器改变实例的状态为挂起或者不活跃, * 依赖于是否这个实例在它创建时是否注册。在之前的情况收集器还会添加实例到挂起引用列表。 最新创建的实例使活跃状态。 * * 挂起状态: 一个挂起引用列表中等待被引用处理线程排队的元素。没有注册的实例不可能有这个状态。 * * 排队状态:一个队列里面的在创建时就被注册的实例元素。当一个实例被从他自己的引用队列移除,他就变成不活跃状态了。没有注册的实例不可能有这个状态。 * * 不活跃状态:无所事事。一个实例变成不活跃状态就不可能再改变状态了。 * * 状态像下面这样被编码到queue和next字段: * * 活跃:实例注册时queue = ReferenceQueue或者如果实例没有被注册queue=ReferenceQueue.NULL;next=null. * * 挂起:实例注册时queue = ReferenceQueue;next=queue里面的下一个实例,如果实例是队列最后一个元素,next=this * * 排队:queue = ReferenceQueue.ENQUEUED;next=queue里面的下一个实例,如果实例是队列最后一个元素,next=this * * 不活跃:queue = ReferenceQueue.NULL; next = this. * * 有了这些约束,收集器为了确定一个引用对象是否需要特别对待只需要检查next字段:如果next字段是null这个实例就是活跃的;如果 * 不为null,这收集器就应该正常对待这个实例了。 * * 为了保证并发收集器能发现活跃引用对象而不干涉可能在这些对象上调用queue()方法的应用线程,收集器应该通过已发现的字段链接已发现的对象。 */ private T referent; //GC要特殊对待的对象 ReferenceQueue<? super T> queue; Reference next; private transient Reference<T> discovered; //VM使用 //对象过去常常是跟垃圾收集器同步的。收集器在每一个收集周期开始时必须获取这个锁。 //因此至关重要的是任何持有这个锁的代码必须尽快完成,不分配新对象,避免调用用户代码。 private static class Lock { }; private static Lock lock = new Lock(); //等待排队的引用列表。当引用处理器线程移除引用,收集器就他们加到这个列表。这个列表被上面的锁对象保护。 private static Reference pending = null; //排队挂起引用的高优先级线程 private static class ReferenceHandler extends Thread { ReferenceHandler(ThreadGroup g, String name) { super(g, name); } public void run() { for (;;) { Reference r; synchronized (lock) { if (pending != null) { r = pending; Reference rn = r.next; pending = (rn == r) ? null : rn; r.next = r; } else { try { lock.wait(); } catch (InterruptedException x) { } continue; } } // Fast path for cleaners if (r instanceof Cleaner) { ((Cleaner)r).clean(); continue; } ReferenceQueue q = r.queue; if (q != ReferenceQueue.NULL) q.enqueue(r); } } } static { ThreadGroup tg = Thread.currentThread().getThreadGroup(); //这个就是取最上层的线程组,看起来写的很溜 //主线程有一个main线程组[Thread[main,5,main], null, null, null] //上面还有一个system线程组[Thread[Reference Handler,10,system], Thread[Finalizer,8,system], Thread[Signal Dispatcher,9,system], Thread[Attach Listener,5,system]]。 for (ThreadGroup tgn = tg; tgn != null; tg = tgn, tgn = tg.getParent()); //启动一个引用处理线程 Thread handler = new ReferenceHandler(tg, "Reference Handler"); //如果还有系统独有的优先级比MAX_PRIORITY这个高,那么就高的 handler.setPriority(Thread.MAX_PRIORITY); handler.setDaemon(true); handler.start(); } /*GC要特殊对待的对象的访问器和设置器*/ /** * 返回当前引用对象的GC要特殊对待的对象,不管这个对象已经被程序还是垃圾收集器清理了都返回null * @return */ public T get() { return this.referent; } /** * 清理这个引用对象,执行这个方法不会引起对象进入排队队列。 * * 这个方法只会被java代码执行;当垃圾收集器执行清理会很直接,不会执行这个方法。 */ public void clear() { this.referent = null; } /*查询操作*/ /** * 告诉你这个引用对象是否一家被加入排队队列,不管是程序或者垃圾收集器干的。如果这个引用对象在创建时没有被注册到队列,这个方法会返回false。 * @return */ public boolean isEnqueued() { //在内部状态中可以看出来,这个方法实际上不管实例是挂起还是排队都会检查到 synchronized (this) { return (this.queue != ReferenceQueue.NULL) && (this.next != null); } } /** * 添加这个引用对象到它注册到的任何队列里面。 * 这个方法只会被java代码执行;当垃圾收集器执行清理会很直接,不会执行这个方法。 * @return 如果这个引用对象被成功加入排队队列返回true,如果它已经被加入了排队队列或者在创建时没有注册到一个队列返回false。 */ public boolean enqueue() { return this.queue.enqueue(this); } /*构造方法*/ Reference(T referent) { this(referent, null); } Reference(T referent, ReferenceQueue<? super T> queue) { this.referent = referent; this.queue = (queue == null) ? ReferenceQueue.NULL : queue; } }

看完后就明白了一个问题,JVM运行的时候至少开启几个线程?(答案是五个!)

转载于:https://www.cnblogs.com/zby9527/p/7464893.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34383618/article/details/93233139

智能推荐

使用GAN生成CIFAR10图像_frank_haha的博客-程序员宝宝_cifar10图像生成

参考肖智清老师的《神经网络与PyTorch实战》import torch.nn as nnimport torch.nn.init as initimport torchimport torch.optimfrom torch.utils.data import DataLoaderfrom torchvision.datasets import CIFAR10import torchvision.transforms as transformsfrom torchvision.utils

win10初始化这台电脑——找不到恢复环境_林锋Space的博客-程序员宝宝_初始化电脑找不到恢复环境怎么办

现象:现象原因:恢复镜像文件丢失解决步骤:1、按住windows键,输入cmd,选择以管理员身份运行2、在DOS下输入reagentc /info可以看到Windows RE状态为Dsiabled,则说明镜像文件丢失3、重新创建Windows RE恢复环境不要再C盘根目录创建Recovery,创建后会消失,即使打开隐藏还是看不到。(1)在C:\新建文件夹\目录下创建名为“Recovery”的文件夹(2)在“Recovery”的文件夹里创建名为"W.

PyTorch学习笔记(1)autograd和backward_梆子井欢喜坨的博客-程序员宝宝

目录1. 一个线性回归的例子2. 使用自动求导3. 优化器1. 一个线性回归的例子例子与代码来自 PyTorch 官方教程书《Deep learning with PyTorch》Deep-Learning-with-PyTorch-Chinese假设你去了一些鲜为人知的地方旅游,然后带回了一个花哨的壁挂式模拟温度计。这个温度计看起来很棒,非常适合你的客厅。唯一的缺点是它不显示单位。不用担心,你有一个计划。你用自己喜欢的单位建立一个读数和相应温度值的数据集,然后选择一个模型,并迭代调整单位的权重,直

【无标题】_全世界最好的佳慧的博客-程序员宝宝

用于实时语义分割的双分割网络(BiseNet)摘要介绍相关工作BiseNet摘要语义分割需要丰富的信息空间和较大的接受区域。然而,现代方法通常会牺牲空间分辨率来实现实时推理速度,这导致了信息的匮乏。在这篇文章中,我们用一种新颖的双边分割网络(BiseNet)来解决这个难题。我们首先设计一个小步幅的SP网络来保存空间信息并生成高分辨率的特征,使用CP(Context Path)采用快速下采样的策略来获取足够的接受域,在这两种方法的基础上,我们引入了一个新的特征融合模块去有效的结合特征。提出的架构

Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure 解决_大可i不必的博客-程序员宝宝

Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure 解决网上说法:1、修改my.cnf:[mysqld]wait_timeout=31536000interactive_timeout=31536000将过期时间修改为1年。2、在连接URL上添加参数:&amp;autoReconnect=true&amp;failOverReadOnly=false都没有解决。

随便推点

【一次过】Lintcode 1013:独特的摩尔斯编码_小马哥MAX的博客-程序员宝宝

摩尔斯电码定义了一种标准编码,把每个字母映射到一系列点和短划线,例如:a-&gt;.-,b-&gt;-...,c-&gt;-.-.。给出26个字母的完整编码表格:[".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-."...

位图与文字_jieniyimiao的博客-程序员宝宝

位图由一个个像素组成,画位图,就是画一个个像素点.如下图像素点越多,那么图片的清晰度就更高。当然由于让一个人用一个个像素画图片,那真是痛苦...so,只是了解下函数而已.OpenGL中画位图的三个步骤一.定位(glRasterPos)假设你画下一个像素点,那么首先则需要确定位置二.定义位图的像素点一个图形由一组像素组成,如下图的F

2022DASCTF Apr X FATE 防疫挑战赛 Writeup_末初mochu7的博客-程序员宝宝

文章目录SimpleFlow熟悉的猫冰墩墩废物选手的misc做题记录SimpleFlow首先tcp.stream eq 50中分析传入的执行命令的变量是$s,也就是参数substr($_POST["g479cf6f058cf8"],2)找到对应的参数,然后去掉前面两位字符解码即可cd "/Users/chang/Sites/test";zip -P PaSsZiPWorD flag.zip ../flag.txt;echo [S];pwd;echo [E]得到压缩包密码:PaSsZi

答疑:一名大四学生的选择_iteye_17103的博客-程序员宝宝

【学生来信】尊敬的贺老师:  你好!  我是XX学院计算机系一名学生,最近逛科学网和CSDN看到了你的文章,你为人师者的精神让我很受敬佩,你所写的博文让人读起来很受启发。很遗憾,到大四才有幸读到你的文章,我是一名准大四生了,现在有一个让我纠结的主要问题,就是考研。  先说一下我的情况吧,我自认为是一个有上进心的学生,也愿意下功夫学习,但计算机这个专业我学得很不怎么地。当时是被调剂到计算机科学与技...

Camunda如何获取(预取)下一审批节点_skayliu的博客-程序员宝宝_camunda动态审批人

在实际业务使用过程中,存在需要当前审批人指定或可修改下一审批节点的审批人(单个或多个),这时候就先要获取到下一审批节点,然后在提交时给引擎传递相应的变量,达到用户指定下一节点审批人的目标。 模型如下图所示: 模型定义文件:&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/2...

javascript挑战编程技能-第八题:99乘法表_陈小聪-小虎Oni的博客-程序员宝宝

今天比较晚,直接进入正题吧!题目:创建一个程序,生成从0到12的乘法表。示例输出0*0=00*1=0...12*11=13212*12=144条件:使用一个嵌套循环来完成该程序。这个没什么好说的,直接上代码吧!前面的输入输出都讲得很详细了,这里直接上主要函数吧。这个很初级,没什么好说的。 var htmlString = "";