我有一种情况,我需要一个线程安全队列,每次调用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);
}
....
不幸的是,我很难弄清楚如何确保对象类型<E>
必须实现可比较的接口,并在尝试对列表进行排序时使用该对象compareTo函数(在代码中我有m_comparator这是未完成/占位符。)
有没有人知道只对remove()进行排序的线程安全队列,或者如何修复自定义集合的开头,以便使用通用对象compareTo函数对列表进行排序。
答案 0 :(得分:2)
看起来你按照必须这样做的方式去做。要强制Comparable
接口,请写
public class BlockingSortOnTakeQueue<E extends Comparable<E>> implements Queue<E> {
...
@Override
public synchronized E remove() {
Collections.sort(m_list);
return m_list.remove(0);
}
}
...虽然使用Collections.sort(m_list, Collections.reverseOrder())
以相反顺序排序可能对您有利,并删除最后一个元素,因为ArrayList
中的速度更快。
最好只识别最小元素,而不是整列整个列表,这可能是O(n)而不是O(n log n)。
答案 1 :(得分:0)
对象可以动态地改变&#34; priority&#34;由于外部因素将它们添加到集合中之后。这也需要线程安全。
那么,如果那些&#34;外部因素&#34;会发生什么?在排序算法运行时更改集合中的对象?它可能会破坏列表,并且您的示例代码不会显示您是如何阻止它发生的。那些&#34;外部因素&#34;如果你想避免这个问题,必须在remove()函数的同一个对象上同步。
此外,如果您的代码成功删除了优先级最高的项目,那么它会导致您的问题,然后,在您可以执行任何您正计划使用它的任何事情之前,它会导致问题,一个&#34;外部因素&#34;运行,并导致仍在集合中的其他对象具有更高的优先级?如果是这样,那么你不需要同步remove()函数,而是需要同步调用remove(),和执行操作的任何代码块。