Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-线程安全集合,在移除/获取时进行排序_Java_Multithreading_Collections_Queue - Fatal编程技术网

Java-线程安全集合,在移除/获取时进行排序

Java-线程安全集合,在移除/获取时进行排序,java,multithreading,collections,queue,Java,Multithreading,Collections,Queue,我需要一个线程安全队列,该队列在每次调用remove()方法时以及仅在调用该方法时运行排序。这是因为在由于外部因素将对象添加到集合后,对象可以动态更改“优先级”。这也需要线程安全。扩展PriorityBlockingQueue之类的东西没有意义,因为在添加内容时,它将运行比较函数。我找不到任何这样的集合/队列,因此我尝试通过环绕数组列表来实现我自己的集合/队列: public class BlockingSortOnTakeQueue<E> implements Queue<E

我需要一个线程安全队列,该队列在每次调用remove()方法时以及仅在调用该方法时运行排序。这是因为在由于外部因素将对象添加到集合后,对象可以动态更改“优先级”。这也需要线程安全。扩展PriorityBlockingQueue之类的东西没有意义,因为在添加内容时,它将运行比较函数。我找不到任何这样的集合/队列,因此我尝试通过环绕数组列表来实现我自己的集合/队列:

public class BlockingSortOnTakeQueue<E> implements Queue<E>
{
    private ArrayList<E> m_list;

    public BlockingSortOnTakeArrayList()
    {
        m_list = new ArrayList<>();
    }


    @Override
    public synchronized E remove() 
    {
        m_list.sort(m_comparator);
        return m_list.remove(0);
    }

    ....
public类BlockingSortOnTakeQueue实现队列
{
私有ArrayList m_列表;
公共封锁SortOnTakeArrayList()
{
m_list=new ArrayList();
}
@凌驾
公共同步删除
{
m_-list.sort(m_-comparator);
返回m_列表。删除(0);
}
....
不幸的是,我很难弄清楚如何确保对象类型
必须实现可比较接口,以及在尝试排序列表时使用该对象比较功能(在代码中,我有一个未完成的m_comparator/占位符)


是否有人知道仅在remove()上排序的线程安全队列,或者如何修复我的自定义集合的开始,以便使用泛型对象比较函数对列表进行排序。

看起来您正在按必须的方式进行排序。要强制执行
Compariable
接口,请编写

public class BlockingSortOnTakeQueue<E extends Comparable<E>> implements Queue<E> {
  ...
  @Override
  public synchronized E remove() {
    Collections.sort(m_list);
    return m_list.remove(0);
  }
}
public类BlockingSortOnTakeQueue实现队列{
...
@凌驾
公共同步删除{
集合。排序(m_列表);
返回m_列表。删除(0);
}
}
…虽然使用
Collections.sort(m_list,Collections.reverseOrder())
按相反顺序排序可能会对您有利,并且可以删除最后一个元素,因为在
ArrayList
中这会更快

最好只确定最小的元素,而不是对整个列表进行排序,整个列表应该是O(n)而不是O(n log n)

由于外部因素,对象在添加到集合后可以动态更改“优先级”。这也需要线程安全

那么,如果这些“外部因素”在排序算法运行时更改集合中的对象,会发生什么情况呢?它可能会损坏列表,并且示例代码没有显示如何防止这种情况发生。如果要避免该问题,这些“外部因素”必须与remove()函数在同一对象上同步


此外,如果您的代码成功删除了最高优先级的项,然后在您可以对其执行任何计划之前,运行了一个“外部因素”,并导致仍然在集合中的其他对象具有更高的优先级,这会给您带来问题吗?如果是这样,那么就不只是同步remove()函数,则需要同步调用remove()的任何代码块,并执行该操作。

您可以说“public class blockingsortonakequeue…”好的地方!我没有想到我只需要通过集合一次就可以找到最小值/最大值,所以排序是不必要的/浪费的。在这种情况下,使用LinkedList,而不是ArrayList。@Programster,同步的find min仍然是一个巨大的潜在瓶颈。您是否考虑过使用优先级队列并让它每次都事先知道ty更改?我最初运行的是priorityqueue,但不知道如何强制重新排序。也许最好的方法是在元素变“脏”时删除/添加它们?@Programster,是的,如果队列相对于更新频率而言较大,这可能是最好的。许多优先级队列实现支持快速递减键操作,您应该尽可能使用该操作。您提出了一个非常好的观点。在扩展我的简化示例的情况下,可能会发生队列顺序损坏。对于我的特定情况,这不是问题lem,但是太冗长了,无法解释。简单来说,如果remove()返回集合中的任何元素,它将是“可接受的”(不会导致错误),但如果它返回“最佳”元素,并且值得花费CPU时间来尝试查找它,则它是理想的。我还将使用对min元素的搜索,而不是Louis Wasserman建议的排序。