当前位置: 首页 > 知识库问答 >
问题:

如果轮询不一定返回第一项,并发链接队列是一个不错的选择吗?

方高丽
2023-03-14

我有一个用例,其中队列保存上传项。队列必须是线程安全的。UploadItem有一个方法canUpload()。UploadItems被添加到尾部的队列中,但是peek()和poll()必须返回第一个UploadItem,其中canUpload()为true。这可能是头部的项目或较新的项目。本质上,我希望项目在准备好上传之前被忽略,并且我希望队列返回准备好的最早的项目。

为了解决这项工作,我扩展了一个并发链接队列,并且我覆盖了 peek() 和 poll()。我已经同步了重写的方法,并且我正在使用迭代器来检索第一个有效项目。

public class UploadQueue extends ConcurrentLinkedQueue<UploadItem> {

    public UploadQueue() {}

    @Override public synchronized UploadItem peek() {
        for (UploadItem item : this) {
            if (item.canUpload()) {
                return item;
            }
        }
        return null;
    }

    @Override public synchronized UploadItem poll() {
        for (UploadItem item : this) {
            if (item.canUpload()) {
                remove(item);

                return item;
            }
        }
        return null;
    }

}

这是一个好的实现,还是可以更有效地完成?使用迭代器检索项目是否有任何不良影响?我不能使用索引和 get() 来选择项目,所以看起来我必须使用迭代器。我也无法跟踪内部变量中的项目,因为它们由外部函数链接和更改。

这将在Android上运行,Android仍然使用Java 6。面对 Java 中的无锁并发链列表和并发链接队列$节点在删除后仍保留在堆中(),是否存在某些 Android 手机可能仍存在 Java 内存泄漏的风险?有谁知道Java是否通常在Android上更新/修补(在其主要版本中)?

共有2个答案

何高歌
2023-03-14

优先级队列比较器结合使用,该比较器首先在 canUpload 上进行比较,然后在日期的相反顺序上进行比较。

方波娃
2023-03-14

这是一个好的实现方式吗?或者可以更有效地实现吗?

这两个标准并不相互排斥。

此外,如果不知道canUpload的成本有多高,队列会有多大,条目在“不可上传”状态下保持多长时间,就不可能说效率是否可能是一个问题。

然而,当然可以更有效地这样做。例如,如果您可以安排从“不可上载”到“可上载”的转换触发某种类型的事件,那么您可以安排事件处理程序将UploadItem添加到队列中。

对< code>UploadItem对象集合的循环扫描可能比每次从队列的开始扫描更有效。其他可能的策略也可能更有效。

但是这些替代方法也可能会改变上传发生的顺序…如果这对您来说是个问题。

使用迭代器检索项目是否有任何不良影响?

ConprestLinkedQueue的迭代器是弱一致性的。这意味着您不能保证看到在迭代开始后添加的条目。这对您的用例来说可能不是问题。(我认为如果下载偶尔被推迟到下一个队列轮询周期,这并不重要。)

这将在Android上运行,Android仍然使用Java 6。面对Java中的无锁并发链表和ConcurrentLinkedQueue$节点在remove()后仍保留在堆中,是否存在某些Android手机可能仍然存在Java内存泄漏的风险?

对我来说,这些问题并不意味着长期内存泄漏。如果存在泄漏,那么当线程丢弃迭代器时,看起来可能会被清除……或者类似的东西。

另一方面,那些Q

有人知道Java是否通常在Android上更新/修补(在其主要版本中)?

你不能一概而论。

首先,Java库的Android实现是与标准Oracle / OpenJDK代码库不同的代码库。因此后者的更新/补丁不适用于前者。

其次,即使对标准的Android发行版进行了更新/补丁,也不能保证1)手机制造商会选择它们,2)它们会进入手机公司的分销渠道,或者3)个人智能手机用户会应用它们。

 类似资料:
  • 问题内容: 我有一个包含多个标签的标签。 我只能为第一个标记设置CSS属性: 但是,我以下尝试为除第一个标签之外的其他每个标签设置CSS属性不起作用: 如何在CSS中编写“除第一个元素外的每个元素”? 问题答案: 一个您发布的版本的实际工作为所有现代浏览器(如CSS选择3级的支持: 如果您需要支持旧版浏览器,或者由于选择器的限制(仅接受一个简单的选择器作为参数)而受到阻碍,则可以使用另一种技术:

  • 问题内容: 如果返回0行,那么我需要。是否可以在带有条件语句的单个MySQL查询中执行此操作? 编辑: 所有答案均有效,但前提是两个查询均从同一表(或具有相同列数的表)中选择。如果第二个查询应用于具有联接的其他表上怎么办? 让我写下我的查询以使问题更清楚: 第一: 如果第一个结果为空,则: 第二名: 如果返回第一个查询,我将使用第一个查询的行,否则将使用第二个查询。 问题答案: 从我刚刚进行的快速

  • 我有一个标签,包含几个标签。 我只能为第一个标记设置CSS属性: 但是,我下面尝试为每个标记设置CSS属性,但第一个除外,但都不起作用: 我如何用CSS写:“每个元素,除了第一个”?

  • 我正在为二和leetcode问题实现一个哈希映射。 映射的第一个数组创建一个散列数组作为“索引”,它是nums数组中每个元素的目标差异。然后,我对映射数组应用一个过滤器,以查看映射数组的2个元素是否包含在nums数组中,并返回这些元素的索引。 当索引被过滤到returnedArr中时,它似乎返回nums的第一个元素,而不是两个索引。[2] 返回之前的日志记录显示它正确地分别注册了索引0和1,而不是

  • 我正在查询URI以从web服务获取一些数据。那很好。但我注意到,我的json hase多页的page\u计数,但只返回第一页数据。 以下是json的样子: 如何返回所有页面而不是只返回第一页?我知道这可能不是个好主意,但我该怎么做? 更新:web服务的URI类似于: 谢谢

  • 问题内容: 我试图加快PHP脚本的速度,目前正在Mysql域中推送一些PHP逻辑。如果第一个Select不返回行或计数为零,是否可以进行其他选择查询? 请记住,第一个查询需要首先运行,并且 仅 当第一个查询返回空集 时才 应激活第二个查询。 对于上面的2个查询,我有这段代码,但似乎每个查询运行两次(一次计数,一次返回)。有一个更好的方法吗? 问题答案: 一种选择是使用有: SQL小提琴演示 这将从