9
|
Steve Jackson · 技术社区 · 15 年前 |
![]() |
1
9
这里实际发生的是remove方法准备了一个轮询线程,以使链接引用为空。 ConcurrentLinkedQueue是一个非阻塞线程安全队列实现。但是,当您尝试从队列中轮询节点时,它是一个双功能过程。首先,您将值设为空,然后将引用设为空。CAS操作是一个单一的原子函数,它不会为轮询提供immidiate解析。 当您轮询时,会发生的情况是,成功的第一个线程将获取节点的值,并将该值置空,然后该线程将尝试将引用置空。然后可能会有另一个线程进入并尝试从队列中进行轮询。为确保此队列包含非阻塞属性(即一个线程的失败不会导致另一个线程的失败),新的传入线程将查看该值是否为空,如果为空,则线程将使引用为空,然后重试poll()。 因此,您在这里看到的是删除线程只是准备任何新的轮询线程来使引用为空。我认为要实现一个非阻塞移除函数几乎是不可能的,因为这需要三个原子函数。该值的空值:引用该节点的空值,最后是从该节点的父节点到其后续节点的新引用。 回答你最后一个问题。不幸的是,没有更好的方法来实现删除和维护队列的非阻塞状态。至少在这一点上。一旦处理器开始与2路和3路套管混合,这是可能的。 |
![]() |
2
1
队列的主要语义是add/poll。如果你使用 污染() 上 ConcurrentLinkedQueue ,它将按应该的方式进行清洁。根据你的描述, 污染() 应该给你删除最旧的条目。为什么不用它代替 移除() ? |
![]() |
3
1
查看1.6.0_29的源代码,CLQ的迭代器似乎被修改为尝试删除带有空项的节点。而不是:
现在代码是:
这是作为修复Bug的一部分添加的: http://bugs.sun.com/view_bug.do?bug_id=6785442 事实上,当我尝试以下方法时,我会得到旧版本的OOME,而不是新版本的OOME:
|
![]() |
a a · 为什么在这个可重入锁示例中需要引用计数? 3 年前 |
![]() |
Grant · goroutines有高空闲唤醒电话 3 年前 |
![]() |
hoaz · 如何安全地清理并发映射 7 年前 |
![]() |
Alanpatchi · int基元类型的volatile声明 7 年前 |