线程中断后仍接收Twitter API数据,如何停止获取?
解决线程中断时停止Twitter API数据获取的问题
咱们先梳理下你当前代码里的几个关键问题,然后一步步修改解决:
问题1:线程启动方式错误
你在start按钮的事件里直接调用r.run(),这不是启动新线程,只是在UI线程里同步执行run方法的代码。所以stop按钮里调用Thread.currentThread().interrupt()中断的是UI线程,完全没触及到执行Twitter请求的逻辑,这肯定没用。
问题2:没有保存目标线程的引用
你没法准确中断执行Twitter请求的线程,因为没保存它的引用,导致stop按钮不知道该中断哪个线程。
问题3:Twitter API调用逻辑不响应中断
就算线程被中断了,你的searchtwitter()方法也没有检查中断状态,会继续执行API请求和数据处理。
修改后的代码示例
1. 修正MainControll类:正确启动线程并保存引用
public class MainControll { TryuingRunabble r; Thread twitterThread; // 保存执行Twitter请求的线程引用 @Override public void initialize(URL location, ResourceBundle resources) { start.addEventHandler(MouseEvent.MOUSE_CLICKED, (e)->{ // 避免重复启动同一个线程,先检查状态 if (twitterThread == null || !twitterThread.isAlive()) { r = new TryuingRunabble(); // 每次启动新的Runnable实例,避免复用已中断的实例 twitterThread = new Thread(r); twitterThread.start(); // 正确启动新线程 } }); stop.addEventHandler(MouseEvent.MOUSE_CLICKED, (e)->{ // 中断目标线程 if (twitterThread != null && twitterThread.isAlive()) { twitterThread.interrupt(); twitterThread = null; } }); } }
2. 修正TryuingRunabble类:处理中断状态
public class TryuingRunabble implements Runnable { ConnectTwitter coT; @Override public void run() { coT = new ConnectTwitter(); try { TimeUnit.MILLISECONDS.sleep(3000); // 执行搜索前先检查是否已中断 if (Thread.currentThread().isInterrupted()) { return; } // 将当前线程传给search方法,方便检查中断 coT.searchtwitter(Thread.currentThread()); } catch (InterruptedException e) { // 捕获中断异常后,重新设置中断标志(异常会清除标志) Thread.currentThread().interrupt(); System.out.println("线程已中断,停止执行"); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | IOException | TwitterException | SQLException e) { e.printStackTrace(); } } }
3. 修改ConnectTwitter类:让API调用响应中断
根据你使用的Twitter API类型(流式搜索或普通分页搜索),在关键节点检查中断状态:
情况A:流式Twitter API(持续获取数据)
public class ConnectTwitter { public void searchtwitter(Thread workerThread) throws TwitterException, IOException { TwitterStream twitterStream = new TwitterStreamFactory().getInstance(); StatusListener listener = new StatusListener() { @Override public void onStatus(Status status) { // 处理每条数据前先检查线程是否中断 if (workerThread.isInterrupted()) { twitterStream.shutdown(); // 关闭流式连接 return; } // 正常处理数据的逻辑 System.out.println("收到推文:" + status.getText()); } // 实现其他StatusListener接口方法 @Override public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) {} @Override public void onTrackLimitationNotice(int numberOfLimitedStatuses) {} @Override public void onScrubGeo(long userId, long upToStatusId) {} @Override public void onStallWarning(StallWarning warning) {} @Override public void onException(Exception ex) { ex.printStackTrace(); } }; twitterStream.addListener(listener); // 设置搜索条件(比如关键词) FilterQuery filterQuery = new FilterQuery(); filterQuery.track(new String[]{"java", "twitter"}); twitterStream.filter(filterQuery); } }
情况B:普通分页搜索(批量获取数据)
public class ConnectTwitter { public void searchtwitter(Thread workerThread) throws TwitterException { Twitter twitter = new TwitterFactory().getInstance(); Query query = new Query("java"); query.setCount(100); // 每次请求100条 do { // 每次请求前检查是否中断 if (workerThread.isInterrupted()) { break; } QueryResult result = twitter.search(query); // 处理每条数据前也检查中断 for (Status status : result.getTweets()) { if (workerThread.isInterrupted()) { return; } System.out.println("收到推文:" + status.getText()); } query = result.nextQuery(); } while (query != null); } }
关键要点总结
- 必须用
Thread.start()启动新线程,而不是直接调用Runnable.run() - 保存目标线程的引用,才能准确中断它
- 捕获
InterruptedException后要重新设置中断标志,确保后续检查有效 - 在Twitter API的请求/处理逻辑中,定期检查线程中断状态,一旦中断就停止API调用并退出
内容的提问来源于stack exchange,提问作者user7185152
相关产品推荐
相关产品推荐

