我有以下代码:
def getIndustryData(String[] theIndustries) {
PrintWriter printWriter = new PrintWriter(new BufferedWriter(new FileWriter("result.txt")))
//Listens to Twitter statuses and carries out the following methods on the status
StatusListener listener = new StatusListener() {
@Override
void onStatus(Status status) {
printWriter.write(status.getLang() + "|||" + status.getText())
printWriter.println()
}
@Override
void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) {
}
@Override
void onTrackLimitationNotice(int numberOfLimitedStatuses) {
}
@Override
void onScrubGeo(long userId, long upToStatusId) {
}
@Override
void onStallWarning(StallWarning warning) {
}
@Override
void onException(Exception ex) {
}
}
TwitterStream stream = new TwitterStreamFactory().getInstance()
stream.addListener(listener)
FilterQuery fq = new FilterQuery()
fq.track(theIndustries)
ExecutorService executor = Executors.newSingleThreadExecutor()
Future<String> future = executor.submit(new Callable<String>() {
@Override
String call() throws Exception {
stream.filter(fq)
return null
}
})
try {
future.get(2, TimeUnit.MINUTES)
} catch (TimeoutException e) {
stream.removeListener(listener)
stream.shutdown()
future.cancel(true)
executor.shutdownNow()
}
}
我正在使用Twitter4J来访问Twitter API。我想将推文写入文件2分钟然后停止。
stream.filter(fq)
方法即使在规定的2分钟后也会运行,并且永远不会达到TimeoutException。我认为在2分钟之后会发现异常并且我可以结束方法但是这不会发生。
答案 0 :(得分:0)
你有关于TwitterStream如何工作的错误心智模型,也很可能是标准java Future
和ExecutorService
的工作方式。
TwitterStream不会处理您提供给它的任何线程。 TwitterStream .filter
内部启动新主题,您可以在https://github.com/yusuke/twitter4j/blob/master/twitter4j-stream/src/main/java/twitter4j/TwitterStreamImpl.java#L317和https://github.com/yusuke/twitter4j/blob/master/twitter4j-stream/src/main/java/twitter4j/TwitterStreamImpl.java#L516
使用Future.get
时,TimeoutException
的超时方法也不能保证失败。如果作业很快,它只返回值。这正是你的情况! stream.filter(fq)
创建新的Thread
,速度很快,然后您的未来会立即返回null
。
使其成功的最简单(但可能不是最好的)方法就是这样
stream.filter(fq)
try
{
Thread.sleep(2 * 60 * 1000); // just sleep on the caller thread
}
catch (InterruptedException e)
{
// ignore
}
stream.removeListener(listener)
stream.cleanup()
//stream.shutdown() //don't think you really need shutdown, cleanup seems to be enough