通过Twitter4J进行多线程Twitter访问

时间:2014-07-11 15:01:00

标签: java multithreading twitter twitter4j

我编写了以下Java代码:

twitterStream.addListener(new StreamListener());

FilterQuery filterQuery = new FilterQuery();
filterQuery.follow(filteringUsers);
filterQuery.track(filteringWords);

twitterStream.filter(filterQuery);

在Twitter中跟踪某些用户和关键字(通过Streaming API)。在这里,StreamListener是我个人对听众的实现。

我正在跟踪很多关键字,主题标签和用户,因此我在内存中累积了很多等待处理的推文。实际上,我只是通过监听器(在onStatus()方法中)并将它们刷新到数据库中。

但是,他们必须在内存中等待的事实显然会在几个小时内使内存饱和。在20分钟的运行中,我在内存中积累了177000个LinkedBlockingQueue$Node个对象和1.272MB的char[](通过剖析看到)。

我想让管道继续运行,显然这在当前状态下是不可能的。

因此,我想知道是否有一种方法可以在多线程中添加多个侦听器,这样它们就可以同时清空推文队列并加快处理速度。

  1. 如果可能:这些侦听器是否同时清空队列?我的意思是:可能有多次读同一条推文的情况吗?
  2. 如果不可能:我该如何解决我的问题?
  3. 提前致谢。

1 个答案:

答案 0 :(得分:1)

虽然通过Twitter4J无法实现直接多线程解决方案,但可以决定通过侦听器类来模拟多线程队列处理。

假设StreamListener是您对StatusListener Twitter4J听众的专长。

我们将StreamListener内的队列复制为私有属性:

private LinkedBlockingQueue<String> tweets;

队列在构造函数中初始化:

tweets = new LinkedBlockingQueue<String>();

此外,在构造函数中,我们构建了一个线程池,用于从队列中读取推文(批量)并将它们存储在数据库中:

    final ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
    Runnable tweetAnalyzer = defineMonitoringRunnable(tweetRepository);
    for (int i = 0; i < NUM_THREADS; i++) {
        executor.execute(tweetAnalyzer);
        try {
            Thread.sleep(THREADS_DELAY);
        } 
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

可以按如下方式构建Runnable对象:

private Runnable defineMonitoringRunnable(final TweetRepository tweetRepository) {
    return new Runnable() {

        @Override
        public void run() {
            List<String> tempTweets = new ArrayList<String>();

            while (true) {
                if (tweets.size() > 0) {
                    tempTweets.clear();
                    tweets.drainTo(tempTweets);

                    tweetRepository.insert(tempTweets);   
                }

                try {
                    Thread.sleep(TWEETS_SAVING_TIME);
                } 
                catch (InterruptedException ex) {
                    ex.printStackTrace();
                }

            }
        }
    };
}

TWEETS_SAVING_TIME是一个推文和另一个推文之间每个Thread对象的等待时间。

最后,onStatus()方法将推文一旦到达侦听器就将其存储在队列中:

@Override
public void onStatus(Status status) {   
    tweets.add(TwitterObjectFactory.getRawJSON(status));
}