Производитель Consumer в Java с использованием потоков никогда не заканчивается

У меня проблема с производителем-потребителем для реализации на Java, где я хочу, чтобы потоки производителей выполнялись в течение определенного времени, например. 1 день, помещая объекты в BlockingQueue -специальные твиты, транслируемые из Twitter Streaming API через Twitter4j- и потребительский поток, чтобы потреблять эти объекты из очереди и записывать их в файл. Я использовал логику ПК из Прочитал 30 миллионов идентификаторов пользователя один за другим из большого файла, где производитель - это FileTask, а потребителем является CPUTask (проверьте первый ответ; мой подход использует те же итерации /try-catch blocks с ним). Конечно, я адаптировал реализации соответственно. Моя основная функция:

public static void main(String[] args) {
    ....

    final int threadCount = 2;

    // BlockingQueue with a capacity of 200
    BlockingQueue<Tweet> tweets = new ArrayBlockingQueue<>(200);

    // create thread pool with given size
    ExecutorService service = Executors.newFixedThreadPool(threadCount);

    Future<?> f = service.submit(new GathererTask(tweets));
    try {
        f.get(1,TimeUnit.MINUTES); // Give specific time to the GathererTask
    } catch (InterruptedException | ExecutionException | TimeoutException e) {
        f.cancel(true); // Stop the Gatherer
    }

    try {
        service.submit(new FileTask(tweets)).get(); // Wait til FileTask completes
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }

    service.shutdownNow();

   try {
        service.awaitTermination(7, TimeUnit.DAYS);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

Теперь проблема заключается в том, что, хотя она передает потоки твитов и записывает их в файл, она никогда не заканчивается и никогда не попадает в часть f.cancel(true). Что я должен изменить, чтобы он работал правильно? Кроме того, не могли бы вы объяснить в своем ответе, что здесь не так с логикой потока, поэтому я узнаю из своей ошибки? Заранее благодарю вас.

Это функции run() для моих классов ПК:

Производитель:

@Override
    public void run() {
        StatusListener listener = new StatusListener(){
            public void onStatus(Status status) {
                try {
                    tweets.put(new Tweet(status.getText(),status.getCreatedAt(),status.getUser().getName(),status.getHashtagEntities()));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    Thread.currentTread.interrupt(); // Also tried this command
            }
        }

        public void onException(Exception ex) {
            ex.printStackTrace();
        }
    };
    twitterStream.addListener(listener);
    ... // More Twitter4j commands
}

Потребитель:

public void run() {
    Tweet tweet;
    try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("out.csv", true)))) {
        while(true) {
            try {
                // block if the queue is empty
                tweet = tweets.take();
                writeTweetToFile(tweet,out);

            } catch (InterruptedException ex) {
                break; // GathererTask has completed
            }
        }
        // poll() returns null if the queue is empty
        while((tweet = tweets.poll()) != null) {
            writeTweetToFile(tweet,out);
        }

    } catch (IOException e) {
        e.printStackTrace();
    }
}

Ответ 1

Вы должны проверить, обрабатывают ли классы Thread в InterruptedException, если нет, они будут ждать всегда. Это может помочь.