阻止队列学习/重复值问题

时间:2017-07-18 15:47:33

标签: java multithreading queue blockingqueue

在创建Producer / Consumer线程进程时,我遇到了一些问题。

所以我使用这个测试代码创建了一个正确放置()和take()的Producer和Consumer。

消费者代码

public class Consumer implements Runnable {
    protected BlockingQueue queue = null;

    public Consumer(BlockingQueue queue) {
        this.queue = queue;
    }
    public void run() {
        while (true)
        {
            try {
                String line = queue.take().toString();
                if(line.equals("EOF"))
                {
                    System.out.println("Capitolism is dead");
                    break;
                }
                System.out.println("Consumed : " + line);
                Thread.sleep(1000);

            } catch (InterruptedException ex) {
                Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}

制作人代码

public class Producer implements Runnable 
{
    private BlockingQueue bq = null;
    public Producer(BlockingQueue queue) {
        this.setBlockingQueue(queue);
    }
    public void run() {
        int value = 0;
        while(true)
        {
            System.out.println(bq.remainingCapacity());
            try {
                bq.put(value);
                System.out.println("Produced : " + value);
                value = value + 1;

                if(value > 10)
                {
                    bq.put("EOF");
                    System.out.println("ChildLabor is Abolished");
                    break;
                }
            } 
            catch (InterruptedException e) 
            {
            e.printStackTrace();
            }
        }
    }
    public void setBlockingQueue(BlockingQueue bq) {
        this.bq = bq;
    }
}

主程序

public static void main(String[] args) throws FileNotFoundException, IOException, InterruptedException 
    {
        java.util.concurrent.BlockingQueue bq = new ArrayBlockingQueue(3);

        Producer producer = new Producer(bq);
        Consumer consumer = new Consumer(bq);

        Thread ConsumerT = new Thread(consumer);
        Thread ProducerT = new Thread(producer);

        ProducerT.start();
        ConsumerT.start();

        ProducerT.join();
        ConsumerT.join();

        System.out.println("FINISHED");
        System.exit(0);
    }

我遇到的问题是当我尝试进入下一个级别时。

我扩展了这段代码,让Producer读取存储每个文件的所有行的文件列表到ArrayList<>中。然后将该arraylist存储在队列中,并且目标是ArrayList<>的队列。然后让消费者阅读并解析。

此时生产者工作正常,它正确读取列表(保持直到队列有一个打开的插槽等)并且所有peak()和take()正常工作。

这个问题似乎在消费者方面,我调用了take()但是一遍又一遍地返回第一个put()对象。

示例输出将是

Produced File 201
Size : 1
Produced File 202
Size : 2
Produced File 203
Size : 3
Consumed File 203
Size : 2
Consumed File 203
Size : 1
Consumed File 203
Size : 0

我并不关心连续3次被叫被叫,更关心文件201如何被反复使用。 Take()正在读取第一个对象,但似乎没有删除它。

我尝试使用remove()peak()的变体来查看头部下方的内容,但这些似乎都不起作用。

为了让它更加混乱,这个过程在没有延迟的情况下工作得很好,当调用put()并在文件处理和头部正常工作后立即调用take()。

看起来像这样

Produced File 201
Size : 1
Consumed File 201
Size : 0

我在尝试解决此问题时获得的其他结果是

Produced File 201
Size : 1
Produced File 202
Size : 2
Produced File 203
Size : 3
Consumed File 203
Size : 2
Consumed File 203
Size : 1

对此有任何帮助或澄清表示赞赏。

修改的 在我上次运行时,我向使用者添加了2个take()调用,这两个调用都返回了相同的值,并且大小队列大小减小了。

同样重要的是要注意take()将始终返回最后一个put(),因此生成的文件201,202,203消耗203 203,生成204,205消耗205,205

0 个答案:

没有答案