当前位置: 首页 > 面试题库 >

java.util.concurrent.LinkedBlockingQueue中的奇怪代码

云宾鸿
2023-03-14
问题内容

所有!

我在LinkedBlockingQueue中发现了奇怪的代码:

private E dequeue() {
        // assert takeLock.isHeldByCurrentThread();
        Node<E> h = head;
        Node<E> first = h.next;
        h.next = h; // help GC
        head = first;
        E x = first.item;
        first.item = null;
        return x;
}

谁能解释为什么我们需要局部变量h?它对GC有什么帮助?


问题答案:

为了更好地了解发生了什么,让我们看看执行代码后列表的样子。首先考虑一个初始列表:

1 -> 2 -> 3

然后h指向headfirst指向h.next

1 -> 2 -> 3
|    |
h    first

然后h.next指向hhead指向first

1 -> 2 -> 3
|   / \
h head first

现在,实际上我们知道只有一个指向第一个元素的活动引用,它本身就是(h.next = h),并且我们还知道GC收集的对象不再具有活动引用,所以当方法结束时,(旧) GC可以安全地收集列表的头部,因为它h仅存在于方法的范围内。

话虽如此,但有人指出,我也同意这一点,即使采用经典的出队方法(即first指向head.nexthead指向first),也没有指向旧头的引用。但是,在这种情况下,旧头仍然悬空在内存中,并且其next字段仍然指向first,而在您发布的代码中,剩下的唯一一个是指向自己的孤立对象。这可能会触发GC动作更快。



 类似资料:
  • 我在登录测试方法中面临奇怪的执行行为。我在selenium网格下运行这段代码。网格配置为独立服务器。因此,首先,我使用批处理文件启动selenium网格(Hub\Node)以通过测试执行。 代码:1. pojDataSource.java: clsConstant。java: 模块测试。java: 当我在Eclipse IDE中以调试模式执行代码时,它向我显示了奇怪的行为。首先,它启动浏览器并打开

  • 大部分人都以为 git 只能合并两个提交,比如 Linux kernel 4.10-rc6 版本最近的提交记录的 hash 是 2c5d955,它的父提交记录分别是: 2c5d955 Merge branch 'parisc-4.10-3' of ... | *- 2ad5d52 parisc: Don't use BITS_PER_LONG in use ... *- 53cd1ad Merge

  • 运行此代码时,在行获得NullPointerException 如果我在调试模式下运行,它会在同一行上停止,但在变量选项卡中,的值可能是原样的,即来自main方法的值。 那么为什么运行时中有NullPointerException呢?

  • 我写了这个Django视图方法: 出于某种原因,第一个代码不起作用,但是如果我做了如下的小修改,它就会开始工作,我不知道为什么。 当我分析修改时: 和 它们看起来很相似,而且都是列表,里面有相同的信息。但是,当对其调用< code>json.dumps方法时,在第一段代码中,它会在浏览器上引发以下错误。

  • 我们有一个在WebLogic10.3.6应用服务器中正常运行的.ear文件。ear使用Spring 3.0.5和Hibernate 3.5.2。 null 好像什么都不管用。我有点迷路了...

  • 我在http://www.nodebeginner.org上读了一篇教程,我在数据输出中有一个奇怪的行为。我知道,Stackoverflow也有类似的问题,但没有答案。所以我有这个Web-Server的代码: 调用RequestHandler.Upload的Router.js代码-我的buggy函数 和RequestHandler.Upload的代码 假设POST数据中有一个字符串。该函数的第一行