Java代理检测方法中Lambda异步任务返回值始终为false如何解决
问题根因
你提交给线程池的任务是异步执行的,主线程调用es.submit()后不会等待异步任务运行结束,会直接执行方法末尾的return false,所以方法返回值永远和异步任务的执行结果无关。
解决方案
同步阻塞返回方案(满足方法返回boolean的需求)
利用ExecutorService.submit()返回的Future对象,阻塞等待异步任务执行完成后获取结果再返回:
final ExecutorService es = Executors.newFixedThreadPool(100); public boolean isProxyOnline(String proxyIp, int proxyPort) { // 提交任务后获取Future对象 Future<Boolean> checkFuture = es.submit(() -> { try { Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyIp, proxyPort)); URLConnection connection = new URL("http://www.google.com").openConnection(proxy); connection.setConnectTimeout(1000); connection.connect(); System.out.println("true"); return true; } catch (Exception e) { System.out.println("false"); return false; } }); try { // 阻塞等待异步任务执行完成,获取返回结果 // 也可以设置最大等待时间,避免无限阻塞:checkFuture.get(2, TimeUnit.SECONDS) return checkFuture.get(); } catch (InterruptedException | ExecutionException e) { // 等待过程被中断、任务执行抛出异常时,返回false e.printStackTrace(); return false; } }
异步回调方案(可选,避免调用线程阻塞)
如果不需要方法同步返回结果,可以改造成回调模式,不阻塞调用线程:
public void checkProxyOnlineAsync(String proxyIp, int proxyPort, Consumer<Boolean> resultCallback) { es.submit(() -> { boolean result; try { Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyIp, proxyPort)); URLConnection connection = new URL("http://www.google.com").openConnection(proxy); connection.setConnectTimeout(1000); connection.connect(); result = true; } catch (Exception e) { result = false; } // 回调返回结果 resultCallback.accept(result); return null; }); } // 调用示例 checkProxyOnlineAsync("127.0.0.1", 8080, isOnline -> { // 处理检测结果 System.out.println("代理是否在线:" + isOnline); });
注意事项
- 如果你需要批量检测大量代理,不要逐个调用同步方法等待结果,建议先把所有任务提交到线程池得到所有
Future对象,再统一遍历获取结果,能最大化利用线程池并发能力,减少整体耗时。 - 同步方案中建议给
get()方法设置超时时间,避免个别代理检测任务长时间卡死导致线程阻塞。
内容的提问来源于stack exchange,提问作者Swipi
相关产品推荐
相关产品推荐

