Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.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 滑动窗口与生产者/消费者线程重叠50%_Java_Android_Guava_Concurrent Collections - Fatal编程技术网

Java 滑动窗口与生产者/消费者线程重叠50%

Java 滑动窗口与生产者/消费者线程重叠50%,java,android,guava,concurrent-collections,Java,Android,Guava,Concurrent Collections,我在Java中有以下场景: 1生产者线程将事件对象存储到队列中。阻止它不是一种选择。它应该始终只将每个元素存储在队列的末尾并退出(因此没有有界队列) 1个使用者线程等待队列中包含窗口大小的事件数。然后,它应该从队列中检索所有窗口大小事件以进行处理,但只删除其中的一半(即窗口大小/2),以实现50%的重叠 我的问题是,您将使用哪个(并发)集合来高效地实现这一点?这些事件在资源有限的设备(运行Android的手机)上以100Hz的频率出现。我曾想过使用以下各项,但似乎没有一项是合适的: Conc

我在Java中有以下场景:

  • 1生产者线程将事件对象存储到队列中。阻止它不是一种选择。它应该始终只将每个元素存储在队列的末尾并退出(因此没有有界队列)
  • 1个使用者线程等待队列中包含窗口大小的事件数。然后,它应该从队列中检索所有窗口大小事件以进行处理,但只删除其中的一半(即窗口大小/2),以实现50%的重叠
我的问题是,您将使用哪个(并发)集合来高效地实现这一点?这些事件在资源有限的设备(运行Android的手机)上以100Hz的频率出现。我曾想过使用以下各项,但似乎没有一项是合适的:

  • ConcurrentLinkedQueue,每次修改时检查队列大小,当窗口大小事件可用时,在使用者中使用peek()/poll()。这似乎有点麻烦
  • 一个ArrayBlockingQueue,再次检查队列大小,并使用drainTo()。但是,该方法具有以下文档:“[…]此外,如果在操作进行过程中修改了指定的集合,则此操作的行为是未定义的。[…]”。对于并发集合来说,这似乎有点奇怪
  • 下面是一些示例代码:

    import java.util.Queue;
    
    import com.google.common.collect.Queues;
    
    public class AccelerometerProcessor implements Runnable {
    
        private static final int WINDOW_SIZE = 128;
    
        private final Queue<AccelerometerEvent> eventQueue = Queues.newConcurrentLinkedQueue();
    
        @Override
        public void run() {
            while (!Thread.interrupted()) {
                try {
                    synchronized (eventQueue) {
                        while (eventQueue.size() < WINDOW_SIZE) {
                            eventQueue.wait();
                        }
    
                        // We have WINDOW_SIZE eventQueue, start processing
                    }
                } catch (InterruptedException e) {
                    // Do nothing
                }
            }
        }
    
        public void addAccelerometerEvent(AccelerometerEvent accelerometerEvent) {
            synchronized (eventQueue) {
                eventQueue.add(accelerometerEvent);
                eventQueue.notifyAll();
            }
        }
    }
    
    import java.util.Queue;
    导入com.google.common.collect.Queues;
    公共类Accelerometer处理器实现可运行{
    私有静态最终整数窗口大小=128;
    private final Queue eventQueue=Queues.newConcurrentLinkedQueue();
    @凌驾
    公开募捐{
    而(!Thread.interrupted()){
    试一试{
    已同步(事件队列){
    while(eventQueue.size()
    顺便说一句,我也在使用谷歌番石榴,所以如果那里有一个不错的收藏,我还没有听说过,请参考我


    那么:有什么好主意可以高效、干净地解决这个问题吗?

    如果你总是要整体消费WINDOW\u SIZE/2事件,为什么生产者线程(你说只有一个)不填充一个SIZE WINDOW\u SIZE/2数组,并在它满后将其传递给队列?

    对于50%的重叠,消费者需要处理WINDOW\u SIZE/2事件,但只消耗/移除其中的一半。但我想你的答案仍然有效。我会考虑的,谢谢!MarkusWüstenberg你是对的,对不起。我的解决方案没有完全描述。生产商仍需提供其中两个阵列。但是消费者可以调用
    data=poll();peek()我不认为完全不清楚。我想最干净的方法应该是计数信号量,但是你听起来好像不想手动实现一些东西。不,我不想讨论信号量。但我将尝试您的方法(实际上是将窗口大小的样本列表传递给列表队列)。再次感谢@MarkusWüstenberg这不会让你每隔一段时间就有100%的重叠吗?你能接受吗?没有料到。嗯,传递的列表的一半内容已从事件队列中删除,另一半已复制。:)这应该是50%的重叠。