У меня проблема с производителем-потребителем для реализации на 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();
}
}